9

我正在 C# 中尝试 ValueTuple 类,我对属性命名有疑问,让我们看看:

如果实例化一个声明对象的 ValueTuple,如下所示:var tuple1 = (Name: "Name1", Age: 25); 我们可以命名属性,

但是,像这样:ValueTuple<string,int> tuple2 = (Name: "Name1", Age: 25);

我们收到一条警告说名称被忽略,所以

我们应该输入:ValueTuple<string,int> tuple2 = ("Name1",25);

那么属性将是tuple2.Item1tuple2.Item2

有人可以解释这个新手的原因吗?

比你更有优势

4

3 回答 3

22

这里涉及两种不同“类型”的元组:.NETValueTuple<...>类型和 C# 元组类型。C# 元组类型可以有元素名称;ValueTuple<...>类型不能。(类型系统中根本没有地方可以正常生活。)

在执行时,一个值只知道它的 .NET 类型。例如,如果您使用:

(string x, int y) tuple1 = ("hello", 10);
(string a, int b) tuple2 = ("hello", 10);
DoSomethingWithValue(tuple1);
DoSomethingWithValue(tuple2);
...
void DoSomethingWithValue(object value) { ... }

那么DoSomethingWithValue根本无法区分这两个元组值。该信息仅在编译时可用。

有关参数和返回类型等元素名称的信息通过 C# 编译器使用的属性传播。例如,一个方法声明如下:

public (string name, int score) GetFoo()

在 IL 中编译,就好像它是这样声明的:

[TupleElementNames(new string[] { "name", "score" }]
public ValueTuple<string, int> GetFoo()

C# 语言定义了 .NET 类型和 C# 元组类型之间的适当转换,以使其尽可能无缝。

在如何使用元组方面,我会尽可能使用 C# 元组类型。命名元组元素在可用性上有很大的不同。

于 2017-10-06T09:03:45.887 回答
1

你要定义的是

(string Name,int Age) tuple1 = (Name: "Name1", Age: 25);

你定义的是

ValueTuple<string,int> tuple2 = (Name: "Name1", Age: 25);

查看您定义的类型之间的区别。如果你取名字,两者都是不同的东西。

于 2017-10-06T08:45:54.530 回答
-1

简而言之:不,您不能使用这样的命名字段创建 ValueTuples。

详细说明:使用 new 创建时查看 Name ValueTuple 属性- 您的问题在那里得到了很好的回答。

于 2017-10-06T08:45:21.870 回答