匿名类数组和对象数组有什么区别?

时间:2014-05-06 15:04:30

标签: c#

我不理解Anonymous Classobject Class

之间的区别

如果我有一个匿名类型对象:

var x = new []
        {
            new {name = "x", phone = 125},
            new {name = "f", phone = 859},
            new {name="s",phone=584}
        };

我可以看到我如何迭代它并获取属性的值x.name ...

但如果我将其更改为object

var x = new Object[]
        {
            new {name = "x", phone = 125},
            new {name = "f", phone = 859},
            new {name="s",phone=584}
        };

然后如果我循环通过它我将无法访问属性? 我已经尝试了不同的方法来从这个对象获取值,但我失败了,可能是我错过了什么?什么是生成object array的问题,我该如何消费呢?

我知道我不能这样做:new Object[] {name = 'x' ...

3 个答案:

答案 0 :(得分:4)

对象数组可以存储任何值。例如,这不会产生任何错误:

var x = new Object[]
        {
            new {name = "x", phone = 125},
            new {name = "f", phone = 859},
            new {name = "s", phone = 584}
        };
x[0] = "foo";

而匿名类的数组强类型为该特定的匿名类。因此,这会产生错误:

var x = new[]
        {
            new {name = "x", phone = 125},
            new {name = "f", phone = 859},
            new {name = "s", phone = 584}
        };
x[0] = "foo"; // Cannot implicitly convert type 'string' to 'AnonymousType#1'

换句话说,编译器确保匿名类的数组元素只是 该匿名类的实例(或null)。

这就是为什么当你写这样的循环时:

for (var instance in x)
    Console.WriteLine(x.name);

x被声明为匿名类的数组时,它将起作用,因为编译器可以推断出该数组的所有元素都是匿名类的实例。但是,当x被声明为对象数组时,编译器无法推断该数组的元素的实际类型(仅限于它们从Object继承,其中包括.NET中的所有值)。

答案 1 :(得分:1)

在这两种情况下,数组都是强类型的。在这两种情况下,数组都包含相同匿名类型的对象。唯一的区别是,在第一种情况下,数组具有匿名对象的类型,因此编译器知道其中对象的属性,而在第二种情况下,编译器不知道这些属性。

  

我尝试过不同的方法来获取此对象的值而我失败了,可能是我错过了什么?

然而,属性仍然存在,您可以通过反射或使用dynamic类型的C#4来访问它们:

var x = new Object[]
    {
        new {name = "x", phone = 125},
        new {name = "f", phone = 859},
        new {name="s",phone=584}
    };
var bigPhone = x.Cast<dynamic>().Where(v => v.phone > 500);
foreach (dynamic item in bigPhone) {
    Console.WriteLine("name={0}, phone={1}", item.name, item.phone);
}

请注意,此解决方案不是使用第一个示例中的静态类型数组的等效替代方法。这只是静态类型丢失时的一种解决方法。

答案 2 :(得分:0)

将变量声明为

var x = new Object[]
    {
        new {name = "x", phone = 125},
        new {name = "f", phone = 859},
        new {name="s", phone=584}
    };

x[whatever]属于Object类型,因此您只能将其用作一个类型。 Object没有namephone字段,因此您自然无法访问它们。