简体   繁体   English

C#7中的C#匿名类型是多余的

[英]Are C# anonymous types redundant in C# 7

Since C# 7 introduces value tuples, is there a meaningful scenario where they are better suited than tuples? 由于C#7引入了值元组,是否有一个有意义的场景,它们比元组更适合?

For example, the following line 例如,以下行

collection.Select((x, i) => (x, i)).Where(y => arr[y.i].f(y.x)).ToArray();

makes the following line 制作以下内容

collection.Select((x, i) => new {x, i}).Where(y => arr[y.i].f(y.x)).ToArray();

redundant. 多余的。

What would be the use case where one is better used over the other (for either performance reasons or optimization)? 什么是一个用于更好地使用另一个的用例(出于性能原因或优化)?

Obviously, if there is a need for more than six fields, tuples cannot be used, but is there something a bit more nuanced to it? 显然,如果需要超过六个字段,则不能使用元组,但它是否有一些细微之处呢?

There are various differences between anonymous types and C# 7 tuples, which may or may not make one more appropriate than the other in certain situations: 匿名类型和C#7元组之间存在各种差异,在某些情况下,它们可能会或可能不会使另一个更合适:

  • C# 7 tuples are ValueTuple<> s. C#7元组是ValueTuple<> s。 That means they are value types while anonymous types are reference types. 这意味着它们是值类型,而匿名类型是引用类型。
  • Tuples allow static typing at compile time since they are a type that can be expressed explicitly. 元组允许在编译时进行静态类型,因为它们是可以显式表达的类型。 As such, you can use them as method arguments, return types, etc. 因此,您可以将它们用作方法参数,返回类型等。
  • Members of an anonymous type are actual properties that exist on the type. 匿名类型的成员是该类型上存在的实际属性。 Tuple items are fields . 元组项是字段
  • The properties of an anonymous type have an actual name, while the fields on a tuple are just named ItemN (for numbers N ). 匿名类型的属性具有实际名称,而元组上的字段仅命名为ItemN (对于数字N )。 The labels are just metadata information that is mostly used by the compiler, and is not persisted with the actual tuple object. 标签只是编译器主要使用的元数据信息,并不与实际的元组对象保持一致。
  • Because creating an anonymous type actually creates a type under the hood, you have a level of type safety with them. 因为创建匿名类型实际上会在引擎盖下创建一个类型,所以它们具有一定的类型安全性。 Since tuples are just generic containers with applied type arguments, you do not have full type safety with them. 由于元组只是具有应用类型参数的通用容器,因此您没有完整的类型安全性。 For example an (int, int) tuple for a size would be fully compatible to an (int, int) tuple for a position , while anonymous types are closed off completely. 例如一个(int, int)元组的尺寸 。将一个完全兼容(int, int)元组的位置上 ,而匿名类型被完全封闭。
  • As Jon Skeet mentioned, the C# 7 tuple syntax is currently not supported in expression trees. 正如Jon Skeet所提到的,表达式树当前不支持 C#7元组语法。

Current answer by @poke is correct and notes differences between tuple and anonymous types. @poke目前的答案是正确的,并注意元组和匿名类型之间的差异。 I'm going to discuss why you would still use them or prefer one over another. 我将讨论为什么你仍然会使用它们或者更喜欢一个而不是另一个。

There are two new c# 7 features that retires anonymous types. 有两种新的c#7功能可以退出匿名类型。 ValueTuples and Records . ValueTuplesRecords

The main reason that you would not use anonymous types is 你不使用匿名类型的主要原因是

  • you can not use anonymous types globally and they are only type safe when used locally. 您不能全局使用匿名类型,并且在本地使用时它们只是类型安全的。 not being local you have to treat it as dynamic object which has significant performance overhead 不是本地的,你必须把它当作具有显着性能开销的dynamic对象

Reasons that you prefer tuple over anonymous types. 您更喜欢使用匿名类型的元组的原因。

  • they are type safe all over the place. 它们在各处都是类型安全的。 (regardless of naming) (不论命名)

  • they can be used as method arguments, type arguments, field and pretty much every where. 它们可以用作方法参数,类型参数,字段以及几乎每个地方。 (yes I said pretty much, there are places that needs to adopt with tuples, its matter of time.) (是的,我说的很多,有些地方需要采用元组,这是时间问题。)

  • since they can be used as type argument, you probably prefer to wrap lightweight set of parameters in single parameter. 因为它们可以用作类型参数,所以您可能更喜欢在单个参数中包含轻量级参数集。 like Stack<(min, mid, max)> Stack<(min, mid, max)>

  • you can change items naming when ever you feel its appropriate, in generic context name item may satisfy and in more specific context you need more specific name too, like car 您可以在感觉合适时更改项目命名,在通用上下文名称item可以满足,并且在更具体的上下文中,您还需要更具体的名称,如car

  • they are implicitly convertible, int, int can be assigned to (int, long) without explicit cast. 它们是隐式可转换的, int, int可以在没有显式转换的情况下分配给(int, long)

  • they are used in Deconstruct s. 它们用于解构 which brings a lot of syntactic sugar to language. 这给语言带来了很多语法糖。

  • you can have multiple assignments and declarations like (int x, int y) = (0, 1) 你可以有多个赋值和声明,如(int x, int y) = (0, 1)

Having all of this features, there is still one reason that you may prefer anonymous type over tuple. 拥有所有这些功能,仍然有一个原因,你可能更喜欢匿名类型而不是元组。

  • Anonymous types are reference type but tuples are value type. 匿名类型是引用类型,但元组是值类型。

but what if you want to use anonymous type globally? 但是如果你想全局使用匿名类型怎么办? do you prefer to have dynamic objects or statically typed objects? 你喜欢动态对象还是静态类型的对象?

The incoming Records feature again defeats anonymous types. 传入的记录功能再次击败匿名类型。 with records you define your class in short, concise and convenient way. 通过记录,您可以简洁,方便地定义您的课程。 not a big deal. 没有大碍。 just a single line 只是一行

public class Point(X, Y);

Type safety all over the place, and you also have reference type in hand. 在整个地方输入安全性,您也有参考类型。 these two new features bring every thing to defeat anonymous types. 这两个新功能使每一件事都能打败匿名类型。

Note that Records are not added yet, we just have to wait. 请注意,记录尚未添加,我们只需要等待。

Only remaining real usage of anonymous types will be 只剩下匿名类型的实际用法

  • they still serve as backward compatible feature 它们仍然作为向后兼容的功能

  • they can be used in Linq queries when you use anonymous type locally. 当您在本地使用匿名类型时,它们可以在Linq查询中使用。 hence I don't say anonymous types are redundant. 因此我不说匿名类型是多余的。

As I said ValueTuples are not compatible with every component yet. 正如我所说,ValueTuples与每个组件都不兼容。 its just matter of time, but this is how its going to be like in future. 这只是时间问题,但这就是未来的情况。

enough arguments. 足够的论点。 in my humble opinion usage of anonymous types becomes rare, old programmers may still use anonymous type in Linq by habit. 在我的拙见中,匿名类型的使用变得罕见,旧的程序员可能仍然习惯使用Linq中的匿名类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM