问题 C#中的匿名类型


// x is compiled as an int 
var x = 10;

// y is compiled as a string 
var y = "Hello";

// z is compiled as int[] 
var z = new[] { 0, 1, 2 };

// ano is compiled as an anonymous type 
var ano = new { x1 = 10, y1 = "Hello" };

ano 创建的对象属性是只读的。我想弄清楚为什么这些属性是只读的。建议表示赞赏?

编辑:

var ano1 = new { x1 = 10, y1 = "Hello" };

var ano2 = new { x1 = 10, y1 = "Hello" };

如果新的匿名类型具有相同顺序的相同数量和类型的属性,它是否与第一个类型具有相同的内部类型?


11078
2017-09-15 18:54


起源

因为那就是它是如何 - 和 不变性 很好。这个允许的一个漂亮的“免费”功能是一个合理的Equals / HashCode自动实现(具有一些基本的健全性,它将保持有效)。这在VB.NET中是不同的(表明它只是一个C#设计决策) Key 需要使用keyword来指定匿名类型的字段是不可变的。 - user2246674
这就是如何在C#标准中定义匿名类型。如果你想让它们变得可变(或者只有一些是可变的),请不要使用匿名类型。 - p.s.w.g
可能重复 为什么C#中的匿名类型的属性是只读的? - mike z
谢谢大家。还有一个问题。我编辑了这篇文章。 - Thilina H


答案:


var 并不意味着“使用匿名类型”,它意味着“编译器,为我找出类型!”。在前三种情况下,类型实际上是“命名”类型 - System.Int32System.String,和 System.Int32[] (在最后一种情况下,编译器也会根据您放在初始化程序中的数组元素的类型推断出数组元素的类型)。

最后一种情况是唯一使用匿名类型的情况。根据设计,C#的匿名类型是 一成不变。首先在语言中添加它们的主要情况是引入LINQ,在生成匿名类型的情况下不需要可变性。通常,不可变类往往会给设计人员带来更少的问题,特别是涉及并发时,因此该语言的设计者决定采用不可变的匿名类型。


14
2017-09-15 18:58



是否有匿名类型的替代方法,允许我在c#中设置值? - Thilina H
@Leez是的。创建一个类型。你似乎正走在“我怎样才能在尽可能少的线上做到这一点”的道路上,虽然现在很方便,但是在你试图对你的代码进行故障排除的2个月后,将会非常令人沮丧。显式类型定义并不是一件坏事。 - Shirik
@Leez我认为使匿名类型成为不可变的背后的逻辑是,如果你想要一个可变类型,你很可能会从这种类型的名称中获益。给自定义类型一个名称可以让你自由地创建这种类型的对象,这些对象可以跨越方法的边界传递而不会跳过箍或使用 dynamic 类型。当然,您可以将一个匿名类型的对象替换为具有相同结构类型的另一个对象(演示)。 - dasblinkenlight


匿名类型是 immutable,即无法改变。

什么是不可变类型?

Eric Lippert的博客


1
2017-09-15 18:59





有趣的声明来自 这里。找到了另一种选择 这里

... [B]确保会员不变,我们确保   hash在对象的生命周期内是常量。这允许匿名   与哈希表等集合一起使用的类型,实际上没有   在修改成员时丢失它们。有很多好处   不可变性,它大大简化了使用的代码   该对象,因为它们只能在创建时分配值   然后才使用(想想线程)


1
2017-09-15 19:02



这是一个很棒的链接,谢谢! - Thilina H