【问题标题】:Array of dynamic | ExpandoObject | with a compressed initialize syntax动态数组 |扩展对象 |使用压缩的初始化语法
【发布时间】:2011-06-15 21:36:49
【问题描述】:

我试图在 c# 中使用 DynamicObject,我需要一个动态数组:

var d = new dynamic[];

效果很好。

编辑:参见下面的 ExpandoObject。

但我也喜欢用这种压缩的初始化新语法用一些数据填充该数组:

var d = new dynamic[] { 
  new {
   Name = "Some",
   Number = 1010
  },
  new {
   Name = "Other",
   Number = 2010
  }
 }

但在这种情况下,所有对象都会获得非动态类型“对象”,并且通过项目循环会给我一个例外:

foreach (dynamic item in d)
{
  @item.Name
  @item.Number
}

错误:“对象”不包含“名称”的定义。我想我只是以错误的方式初始化数组项。如何改为添加动态对象?

编辑:新内容:

我意识到“动态”没有动态添加属性的能力。

我最好使用 ExpandoObject,它将内部字典中的所有项目作为属性公开。但不幸的是 ExpandoObject 似乎不支持这种漂亮的压缩创建语法,编译器抱怨:

var d = new ExpandoObject[]{
new ExpandoObject(){
    Name="Nnn",
    Number=1080
    }
}

所以答案可能只是:不可能。

【问题讨论】:

  • 你确定你不只是想要一个匿名类型的数组吗?
  • 这是在 ASP.NET MVC3 中吗?
  • 请记住,dynamic object,只是 C# 编译器对它的处理方式不同,并将 dynamic 上的所有访问权限转移到 DLR
  • foreach 正在使用 Razor 是的。和匿名类型 - 是的,如果它有效,我会在那里得到同样的错误 - 那是当我尝试动态时:)
  • @joeriks:您是否尝试过对数组的每个元素进行显式强制转换?这有点讨厌,但它可能会起作用。

标签: c# dynamic object-initializers


【解决方案1】:

我来的有点晚,但我发现了这件事:

如果我不能初始化一个 ExpandoObject,用动态类型初始化它怎么样?

所以我做了以下扩展方法

    public static ExpandoObject CreateExpando(this object item)
    {

        var dictionary = new ExpandoObject() as IDictionary<string, object>;
        foreach (var propertyInfo in item.GetType().GetProperties())
        {
            dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(item, null));
        }
        return (ExpandoObject)dictionary;
    }

我知道这远非理想,但这是我目前能达到的最好水平,它的工作原理如下:

var myExpandoObject = new { Name="Alex", Age=30}.CreateExpando();

【讨论】:

  • 如果我的投影存储在一个函数中,我可以使用这个扩展方法吗?例如:someQueryable.Select(ReusableProjection().ToExpando()),其中ReusableProjection 返回:Expression&lt;Func&lt;SomeType, dynamic&gt;&gt;
【解决方案2】:

开源框架Impromptu-Interface 有一个compressed initialization syntax 可以与ExpandoObject 一起使用。

dynamic @new = Builder.New<ExpandoObject>();

var d = @new.List( 
  @new.Expando(
   Name:"Some",
   Number: 1010
  ),
  @new.Expando(
   Name:"Other",
   Number: 2010
  )
 );

【讨论】:

  • 酷,我来即兴看看。
【解决方案3】:

希望你真的不需要动态

class Program
{
    static void Main(string[] args)
    {
        var d = new[]
                    {
                        new
                            {
                                Name = "Some",
                                Number = 1010
                            },
                        new
                            {
                                Name = "Other",
                                Number = 2010
                            }
                    };
        foreach (var item in d)
        {
            string s = @item.Name;
            int n = @item.Number;
            Console.WriteLine("{0} {1}", s, n);
        }
    }
}

【讨论】:

  • 是的,所以我想,我也尝试过 - 但这给了我同样的错误。嗯……
  • @joeriks - 添加了我正在启动的整个代码片段,我没有任何错误。
  • @joeriks - 如果它与 ASP.Net MVC 相关,那么您可能应该相应地标记问题。我不确定我的答案与 Razor 行为有何关联。
  • 是的 - 它确实与我的上下文有关。问题是我将数组作为 Page 动态对象的成员发送。当我 - 像你一样 - 参加同一个班级时,一切都很好。而且 - 我发现工作代码和我的真实代码之间的 d 对象的唯一不同之处在于,在工作代码示例中,GetType 返回 f__AnonymousType02[System.String,System.String][] but in my real code a GetType returns &lt;&gt;f__AnonymousType12[System.String,System.String][]。 (当我对对象执行 ToString 时,这也是不同的)。现在 1 / 0 对我的对象有用吗?
  • 我认为在这种情况下 Anonymous 类型的问题与tomasp.net/blog/cannot-return-anonymous-type-from-method.aspx 这里描述的相同 - 这让我回到了我原来的问题,我可以用动态的方式来代替吗?
猜你喜欢
  • 2018-07-03
  • 2016-09-16
  • 1970-01-01
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多