'System.Collections.Generic.IList<object>' does not contain a definition for 'Add' when using 'dynamic' and 'ExpandoObject'

后端 未结 2 1088
攒了一身酷
攒了一身酷 2021-02-18 15:30

Say that I have a class, Foo, looking something like this:

public class Foo : IFoo
{
    public Foo()
    {
        Bars = new List();
    }
    p         


        
相关标签:
2条回答
  • 2021-02-18 16:15

    This is a known dynamic binding issue.

    Here are some work arounds.

    Use ICollection<dynamic> instead:

    void Main()
    {
        IFoo foo = new Foo();
        dynamic a = new System.Dynamic.ExpandoObject();
        a.Prop = 10000;
        dynamic b = new System.Dynamic.ExpandoObject();
        b.Prop = "Some Text";
        foo.Bars.Add(a);
        foo.Bars.Add(b); 
    }
    
    public interface IFoo
    {
        ICollection<dynamic> Bars { get; set; }
    }
    
    public class Foo : IFoo
    {
        public Foo()
        {
            Bars = new List<dynamic>();
        }
    
        public ICollection<dynamic> Bars { get; set; }
    }
    

    Or straight up List<dynamic>:

    public interface IFoo
    {
        List<dynamic> Bars { get; set; }
    }
    
    public class Foo : IFoo
    {
        public Foo()
        {
            Bars = new List<dynamic>();
        }
    
        public List<dynamic> Bars { get; set; }
    }
    

    Or use dynamic foo:

    void Main()
    {
        dynamic foo = new Foo();
        dynamic a = new System.Dynamic.ExpandoObject();
        a.Prop = 10000;
        dynamic b = new System.Dynamic.ExpandoObject();
        b.Prop = "Some Text";
        foo.Bars.Add(a);
        foo.Bars.Add(b); 
    }
    

    Or don't dynamic bind add, by casting to object:

    void Main()
    {
        IFoo foo = new Foo();
        dynamic a = new System.Dynamic.ExpandoObject();
        a.Prop = 10000;
        dynamic b = new System.Dynamic.ExpandoObject();
        b.Prop = "Some Text";
        foo.Bars.Add((object)a); 
        foo.Bars.Add((object)b); 
    }
    

    Or be more expressive using a third party framework like my impromptu interface with ActLike & Prototype Builder Syntax (in nuget).

    using ImprmoptuInterface;
    using Dynamitey;
    void Main()
    {
        dynamic New = Builder.New<ExpandoObject>();
    
        IFoo foo = Impromptu.ActLike(
                       New.Foo(
                           Bars: New.List(
                                     New.Obj(Prop:10000),
                                     New.Obj(Prop:"Some Text")
                                 )
                           )
                       );
    }
    
    public interface IFoo
    {
        IList<dynamic> Bars { get; set; }
    }
    
    0 讨论(0)
  • 2021-02-18 16:23

    I'm not sure if this subverts your particular use case, but:

    Try explicitly casting Bars to System.Collections.IList.

    ((System.Collections.IList)foo.Bars).Add(a);
    

    Source: https://stackoverflow.com/a/9468123/364

    Alternatively, just redefine Bars as IList rather than IList<dynamic> in your interface + class.

    0 讨论(0)
提交回复
热议问题