【问题标题】:Why can't the properties of anonymous types be swapped within arrays?为什么不能在数组中交换匿名类型的属性?
【发布时间】:2019-04-22 13:53:43
【问题描述】:

我知道在 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 = "" }
};

为什么不允许这样做,因为在 normal 对象中,无论它们的顺序如何,都可以声明属性,并且其余代码可以使用它们,就像现在一样?

【问题讨论】:

  • 这可能是为了简化编译器和哈希码的生成,并防止ToString() 输出的差异,但我不确定我们中的任何人都可以解释为什么特定的设计做出了决定。
  • @Amy 这确实是一个关于编译器设计的问题,而不是关于如何做某事的问题,在这种情况下确实有少数人可以完全回答。我只是希望能得到最接近现实的答案。

标签: c# arrays .net anonymous-types


【解决方案1】:

来自匿名类型的文档:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/anonymous-types

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

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

【讨论】:

  • 没错。我还建议在答案中添加this link,以帮助澄清两种匿名类型之间的编译差异。
  • 在这种情况下,我不确定它是否有帮助。我们已经知道编译器正在生成两种类型,一种用于每个属性序列。看到编译器生成的代码很有趣,但这只是证实了我们所知道的。
  • 我可以看到编译器不允许将两个具有交换属性的不同匿名对象声明到一个数组中,但这是为什么呢?我的意思是实施起来成本高昂而且不值得,还是其他原因?
  • 这不是一个答案,而是一个需要考虑的场景:如果不是两个属性,而是更多——比如说二十个——并且两个声明的顺序完全不同,该怎么办。从技术上讲,编译器可以对其进行分类并确定它们是同一类型,但看起来真的很混乱。如果您认为它们是相同的,但编译器说它们不是,您将如何解决?您必须对所有属性进行排序以找出差异所在。
  • 确实,我相信他们没有理由允许属性以不同的顺序排列,所以这就是编译器现在给出这个错误的原因。 @ScottHannen 请用 @ 符号标记人们,以便在您回复他们时收到通知:)
【解决方案2】:

尽管 Scott 给出的答案几乎是正确的,但它并没有完全回答 为什么 的问题。由于这是一个关于匿名类型数组的编译器设计的更多问题,而且我们大多数人都无法给出明确的答案,因此我将保持问题的开放性并推迟接受答案,直到有人回答 为什么 em>问题。同时,我将在这里留下以下理论:

问题

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

为什么不呢?

由于现在可以声明一组匿名类型,因此能够交换对象内属性的顺序对任何人都没有帮助。

与此相反,在匿名类型数组的对象中更改匿名对象的属性顺序可能会产生误导,为了保持一致性应该避免。在这种情况下,应该为试图交换对象属性的程序员显示一个警告或至少一条消息,所以为什么不从一开始就让它成为一个错误并消除使 C# 编译器智能的需要足以整理属性本身。

结论:始终保持相同顺序的属性并不是缺少的功能,而是一种特性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多