使用“dynamic”和“ExpandoObject”时,“System.Collections.Generic.IList”不包含“Add”的定义
2024-01-24

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

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

IFoo 界面如下所示:

public interface IFoo
{
    IList<dynamic> Bars { get; set; }
}

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

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!!!!!

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


这是已知的动态绑定issue https://web.archive.org/web/20130609133940/http://connect.microsoft.com/VisualStudio/feedback/details/534288/ilist-dynamic-cannot-call-a-method-add-without-casting.

这里有一些解决方法。

Use 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; }
}

或者直接向上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); 
}

或者不要动态绑定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); 
}

或者使用第三方框架(例如我的即兴界面)更具表现力ActLike https://github.com/ekonbenefits/impromptu-interface/wiki/UsageBasic & 原型生成器语法 https://github.com/ekonbenefits/dynamitey/wiki/UsageBuilder(在 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; }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用“dynamic”和“ExpandoObject”时,“System.Collections.Generic.IList”不包含“Add”的定义 的相关文章

随机推荐