C# 为什么可以';匿名类型的属性不能在数组中交换吗?

C# 为什么可以';匿名类型的属性不能在数组中交换吗?,c#,arrays,.net,anonymous-types,C#,Arrays,.net,Anonymous Types,我知道在C#中,我可以声明一个匿名类型数组,如下所示: var anons = new[] { new { name = "" , something = ""}, new { name = "", something = "" } }; 我可以理解,所有对象都需要具有相同的属性,否则就无法遍历它们并使用这些属性,如: foreach (var anon in anons) { Console.WriteLine(anon.name); } 但我不明白的是,为什么它们

我知道在C#中,我可以声明一个匿名类型数组,如下所示:

var anons = new[]
{
    new { name = "" , something = ""},
    new { name = "", something = "" }
};
我可以理解,所有对象都需要具有相同的属性,否则就无法遍历它们并使用这些属性,如:

foreach (var anon in anons)
{
    Console.WriteLine(anon.name);
}
但我不明白的是,为什么它们的属性需要具有相同的顺序?

例如,以下代码将无法编译:

var anons = new[]
{
    new { name = "" , something = ""},
    new { something = "", name = "" }
};

为什么不允许这样做,因为在普通对象中,可以声明属性,而不管它们的顺序如何,其余的代码可以使用它们,就像现在一样?

来自匿名类型文档:

如果程序集中的两个或多个匿名对象初始值设定项指定了顺序相同且名称和类型相同的属性序列,则编译器会将这些对象视为相同类型的实例。它们共享相同的编译器生成的类型信息


换句话说,您正在创建两个匿名类型,并且属性名称和属性类型的顺序不匹配。它们在我们看来几乎相同,但编译器将它们视为两种不同的类型,这意味着它无法为数组声明推断出一种类型。

尽管Scott给出的答案实际上是正确的,但它不能完全回答“为什么”问题。由于这是一个关于匿名类型数组的编译器设计的问题,而我们大多数人都不能给出一个明确的答案,因此我将保留这个问题,并推迟接受答案,直到有人回答“为什么”问题。同时,我将在这里留下以下理论:

回答这个问题

为什么它们的属性需要具有相同的顺序

为什么不呢

因为现在可以声明匿名类型的数组,所以有可能交换对象中属性的顺序对任何人都没有帮助

与此相反,在匿名类型数组的对象中更改匿名对象属性的顺序可能会产生误导,并且为了一致性,应该避免这样做。在这种情况下,对于试图交换对象属性的程序员,应该显示一条警告或至少一条消息,这样为什么不从一开始就将其设置为一个错误,并且不需要使C#编译器足够智能,以自行整理属性呢


总之:让属性始终保持相同的顺序不是缺少的功能,而是一个特性。

这可能是为了简化编译器和哈希代码的生成,并防止在
ToString()
输出中出现差异,但是我不确定我们中的任何人都能解释为什么会做出一个特定的设计决定。@Amy这实际上更多的是一个关于编译器设计的问题,而不是一个关于如何做某事的问题,在这种情况下,确实有一些人可以完全回答这个问题。我只是希望得到最接近现实的答案。没错。我还建议在答案中添加,以帮助澄清这两种匿名类型在编译方面的差异。在这种情况下,我不确定这是否有帮助。我们已经知道编译器正在生成两种类型,每个属性序列一种。看到编译器生成的代码很有趣,但它只是证实了我们所知道的。我可以看到编译器不允许在数组中声明两个不同的匿名对象,但为什么?我的意思是,它的实现成本太高,只是不值得,还是其他什么?这不是一个答案,而是一个需要考虑的场景:如果不是两个属性,而是更多的属性(比如说二十个),并且两个声明的顺序完全不同,会怎么样。从技术上讲,编译器可以对其进行分类,并判断它们是同一类型的,但这确实会让人感到困惑。如果你认为它们是一样的,但编译器说它们不是,你会怎么想?您必须对所有属性进行排序,以找出差异所在。事实上,我认为它们没有理由允许属性按不同顺序排列,因此这就是编译器现在给出此错误的原因。和@ScottHannen请用@symbol标记人员,以便在您回复他们时通知他们:)