使用'dynamic'和'ExpandoObject'时,'System.Collections.Generic.IList <object>'不包含'Add'的定义

Kod*_*odo 19 .net exception dynamic expandoobject

假设我有一个类,Foo,看起来像这样:

public class Foo : IFoo
{
    public Foo()
    {
        Bars = new List<dynamic>();
    }
    public IList<dynamic> Bars { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

接口IFoo看起来像:

public interface IFoo
{
    IList<dynamic> Bars { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在,当我执行以下操作时:

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); // Throws an 'System.Collections.Generic.IList<object>' does not contain a definition for 'Add' - exception!!!!!
foo.Bars.Add(b); // Same here!!!!!
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?????

jbt*_*ule 24

这是一个已知的动态绑定问题.

这是一些工作.

ICollection<dynamic>改为使用:

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; }
}
Run Code Online (Sandbox Code Playgroud)

或直接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; }
}
Run Code Online (Sandbox Code Playgroud)

或使用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); 
}
Run Code Online (Sandbox Code Playgroud)

或者不要动态绑定add,通过强制转换为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); 
}
Run Code Online (Sandbox Code Playgroud)

或者使用第三方框架更具表现力,例如我与ActLikePrototype Builder语法(在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; }
}
Run Code Online (Sandbox Code Playgroud)