匿名类型和元组

44

匿名类型和元组有什么区别?


2
这里有一篇文章,解释了你想要的内容:http://msdn.microsoft.com/zh-cn/vcsharp/ee957397.aspx - Petar Minchev
5个回答

44

鉴于 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());
}

太酷了。


4
请记住,这些元组并不同于传统的元组或匿名类型。它们是值元组,是带有字段的结构体,而匿名类型则是带有属性的类。 - Michael Yutsis

23

元组不是匿名类型,它是一个命名类型。你可以将其用作返回类型或方法参数。以下代码是有效的:

Tuple<int, string> GetTuple()
{
    return Tuple.Create(1, "Bob");
}
你不能使用匿名类型实现这个功能,你需要返回System.Object。通常情况下,你不得不使用反射来获取这些对象的属性值(或在.NET 4中使用动态类型dynamic)。另外,正如Brian所提到的,元组Tuple的属性名是固定的,它们总是Item1Item2Item3等等,而使用匿名类型时,你可以选择属性名。如果你写:
var x = new { ID = 1, Name = "Bob" }

那么这个匿名类型实际上具有IDName属性。但是如果你写:

Tuple.Create(1, "Bob")

那么产生的元组就只有属性 Item1Item2


3
有关名称部分的“始终是 Item1Item2”在 C# 7 中不再正确。请参见上面 @alex-dresko 的回复。 - codeMonkey
即使Item1和Item2的属性名为ID和Name,它们仍然可以使用。此时,item1将引用ID。这在C#7及以上版本中可行。 - Michael Santos

19

匿名类型拥有携带更多信息的属性名称,而元组则没有。但是你可以使用元组作为返回值和参数,而匿名类型则不行。

当你想要返回多个值时,使用元组会很方便,比如 @Petar Minchev 在这个链接中举了一个很好的例子。

例如,你可能需要一个 Find() 方法来返回索引和值两个结果,又或者是在二维或三维平面上的位置。


这是一个11年前的答案,所以我不确定它是否相关,但匿名类型可以用作返回值。 - Theodor Solbjørg

8

匿名类型的另一个优点是您可以轻松拥有超过8个属性。虽然使用元组可以完成这项工作,但并不美观。

var tuple = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9)); //and so on

或者编写自己的元组类。


有趣的相似之处在于,元组和匿名类型都能给你提供不可变性和基于属性默认重写EqualsGetHashCode的相等比较。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接