Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么.NET中的匿名类型实现为引用类型?_.net_Linq_Performance_Anonymous Types_Value Type - Fatal编程技术网

为什么.NET中的匿名类型实现为引用类型?

为什么.NET中的匿名类型实现为引用类型?,.net,linq,performance,anonymous-types,value-type,.net,Linq,Performance,Anonymous Types,Value Type,因为匿名类型无论如何都是只读的,所以如果将其实现为结构,则is将更加高效,这样linq查询就不需要创建大量临时对象: // This doesn't make any sense, it is just for demonstration var result = thingies .Select(x=> new {A = 1, B = 2, C = 3}); 顺便说一句,我什么时候有这个想法的 编辑: 最重要的是,编译器是否会根据变量的大小和用法(如果必须传递给许多方法),决定是否使用

因为匿名类型无论如何都是只读的,所以如果将其实现为结构,则is将更加高效,这样linq查询就不需要创建大量临时对象:

// This doesn't make any sense, it is just for demonstration
var result = thingies
.Select(x=> new {A = 1, B = 2, C = 3});
顺便说一句,我什么时候有这个想法的

编辑:

最重要的是,编译器是否会根据变量的大小和用法(如果必须传递给许多方法),决定是否使用值类型或引用类型

但我在msdn中发现的以下句子是否会导致问题:

如果同一程序集中的两个或多个匿名类型具有相同的 属性的数量和类型,按照编译器处理的相同顺序 它们是同一类型的


由于匿名对象(及其关联类型)无法离开中定义的方法,我们这里没有问题,是吗?

完整的.NET垃圾收集器针对两种情况进行了特别优化:持续大量时间的大型长寿命对象和快速消亡的小型短命对象。考虑到Gen0集合的速度有多快,它实际上是免费的(事实上,它是如此的快速和频繁,以至于许多探查器甚至懒得显示它们或它们的内容),因此几乎没有理由避免临时集合进入创建它们的函数的范围


匿名类型几乎完全符合第二种情况;它们并不意味着比创建它们的函数更长寿(尽管你可以通过一些技巧来实现)。考虑到这种模型,考虑到大多数值类型的复制成本相对较高,并且考虑到许多LINQ查询涉及一长串函数,这些函数都需要另一个副本,对我来说,设计师选择让它们成为引用类型是有道理的。

如果匿名类型是值类型,我相信我可以做一些基准测试,显示所有复制是多么可怕,它们应该是引用类型,这样就不必到处复制。这两种方法都有好处和折衷,语言设计者选择使用引用类型;我怀疑是因为引用类型比值类型更常见、更容易理解,并且使用的API也更多


不过,最大的速度并不是匿名类型的重点。它们是为90%执行大小合理的LINQ查询的开发人员构建的,他们需要中间类型来存储结果。对于需要数百万个对象的10%,我建议他们创建一个具体类型,并投入一些优化时间。

我不确定您的示例代码如何演示任何东西。。。尽管如此,这还是一个有趣的问题,+1实现结构而不是类往往意味着更多的复制,而不是更少的复制。@Damien,是的,但是引用类型给GC@Thomas-在使用匿名类型的大多数情况下,我希望它们最终会出现在堆分配的对象(如集合)中。它们倾向于对GC施加与类相同的压力。对于Tuple,可以提出一个非常类似的论点。我知道.NET中的内存分配相对便宜,但据我所知,这并不重要。这是一个很好的回答。但愿我能不止一次投票。