匿名类型和元组有什么区别?
匿名类型和元组有什么区别?
鉴于 C# 7 已经发布,我来更新一下这个答案。元组现在拥有超级能力,有时可以替代匿名类型和类。例如,以下方法接受并返回具有命名属性的元组。
为了帮助说明可能性,Whatever
函数会转换输入的形状和值。
void Main()
{
var tupleInput = (Neat: 123, Cool: true);
var tupleOutput = Whatever(tupleInput);
Debug.Assert(tupleOutput.Something == 133);
Debug.Assert(tupleOutput.Another == "True");
}
(int Something, string Another) Whatever((int Neat, bool Cool) data)
{
return (Something: data.Neat + 10, Another: data.Cool.ToString());
}
太酷了。
元组不是匿名类型,它是一个命名类型。你可以将其用作返回类型或方法参数。以下代码是有效的:
Tuple<int, string> GetTuple()
{
return Tuple.Create(1, "Bob");
}
你不能使用匿名类型实现这个功能,你需要返回System.Object
。通常情况下,你不得不使用反射来获取这些对象的属性值(或在.NET 4中使用动态类型dynamic
)。另外,正如Brian所提到的,元组Tuple
的属性名是固定的,它们总是Item1
,Item2
,Item3
等等,而使用匿名类型时,你可以选择属性名。如果你写:var x = new { ID = 1, Name = "Bob" }
那么这个匿名类型实际上具有ID
和Name
属性。但是如果你写:
Tuple.Create(1, "Bob")
那么产生的元组就只有属性 Item1
和 Item2
。
Item1
、Item2
”在 C# 7 中不再正确。请参见上面 @alex-dresko 的回复。 - codeMonkey匿名类型拥有携带更多信息的属性名称,而元组则没有。但是你可以使用元组作为返回值和参数,而匿名类型则不行。
当你想要返回多个值时,使用元组会很方便,比如 @Petar Minchev 在这个链接中举了一个很好的例子。
例如,你可能需要一个 Find()
方法来返回索引和值两个结果,又或者是在二维或三维平面上的位置。
匿名类型的另一个优点是您可以轻松拥有超过8个属性。虽然使用元组可以完成这项工作,但并不美观。
var tuple = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9)); //and so on
或者编写自己的元组类。
有趣的相似之处在于,元组和匿名类型都能给你提供不可变性和基于属性默认重写Equals
和GetHashCode
的相等比较。
别忘了 ValueTuple :)
这三者的关键区别:
名称 | 访问修饰符 | 类型 | 自定义成员名称 | 解构支持 | 表达式树支持 |
---|---|---|---|---|---|
匿名类型 | internal | class | ✔️ | ❌ | ✔️ |
元组 | public | class | ❌ | ❌ | ✔️ |
ValueTuple | public | struct | ✔️ | ✔️ | ❌ |
来源:https://learn.microsoft.com/zh-cn/dotnet/standard/base-types/choosing-between-anonymous-and-tuple