由于C#7引入了值元组,是否有一个有意义的场景,它们比元组更适合?
例如,以下行
collection.Select((x, i) => (x, i)).Where(y => arr[y.i].f(y.x)).ToArray();
制作以下一行
collection.Select((x, i) => new {x, i}).Where(y => arr[y.i].f(y.x)).ToArray();
多余的。
一个用例比其他用户更好(出于性能原因还是优化)会有什么用?
显然,如果需要超过六个字段,则不能使用元组,但它是否有一些细微之处?
答案 0 :(得分:12)
匿名类型和C#7元组之间存在各种差异,在某些情况下可能会或可能不会使另一个更合适:
ValueTuple<>
个。这意味着它们是值类型,而匿名类型是引用类型。ItemN
(对于数字N
)。标签只是元数据信息,主要由编译器使用,并不与实际的元组对象保持一致。(int, int)
元组与位置的(int, int)
元组完全兼容,而匿名类型则完全关闭。 答案 1 :(得分:1)
@poke的当前答案是正确的,并注意元组和匿名类型之间的差异。我将讨论为什么你仍然会使用它们或者更喜欢一个而不是另一个。
有两种新的c#7功能可以退出匿名类型。 ValueTuples和Records。
您不使用匿名类型的主要原因是
dynamic
对象您更喜欢使用匿名类型的原因。
它们在所有地方都是类型安全的。 (无论命名如何)
它们可以用作方法参数,类型参数,字段以及几乎每个地方。 (是的,我说的很多,有些地方需要采用元组,这是时间问题。)
因为它们可以用作类型参数,所以您可能更喜欢在单个参数中包含轻量级参数集。比如Stack<(min, mid, max)>
您可以在感觉合适时更改项目命名,在通用上下文名称item
中可以满足,在更具体的上下文中,您也需要更具体的名称,例如car
它们是隐式可兑换的,int, int
可以在没有明确演员的情况下分配给(int, long)
。
它们在Deconstruct中使用。这给语言带来了很多语法糖。
您可以拥有多个分配和声明,例如(int x, int y) = (0, 1)
拥有所有这些功能,还有一个原因是你可能更喜欢匿名类型而不是元组。
但是如果你想全局使用匿名类型怎么办?你喜欢动态对象还是静态类型对象?
传入的记录功能再次击败匿名类型。通过记录,您可以简洁,方便地定义您的课程。没有大碍。只需一行
public class Point(X, Y);
在整个地方输入安全性,并且您手头也有参考类型。这两个新功能可以打败匿名类型。
请注意,记录尚未添加,我们只需等待。
只有剩余的匿名类型实际使用
它们仍可作为向后兼容功能
当您在本地使用匿名类型时,它们可以在Linq查询中使用。因此,我不是说匿名类型是多余的。
正如我所说,ValueTuples与每个组件都不兼容。这只是时间问题,但这就是未来的情况。
足够的论点。在我看来,匿名类型的使用变得罕见,老程序员可能仍然习惯在Linq中使用匿名类型。