以下只是一个关于语言本身的问题,在开始构建我的代码之前,我开始考虑这个问题,但它让我感兴趣。
如果我有这种结构的方法
private void Foo<T>(T bar){
//do stuff with tuples
}
在不同的类和方法中,我有一个变量
(int first, int second) myTuple = (1,2);
在这个变量的范围内,我可以做像
这样的事情var firstValue = myTuple.first;
无论如何我可以将myTuple
传递给Foo
,这样可以保持元组中元素的命名,这样我就可以做bar.firstValue
之类的事情了吗?
答案 0 :(得分:5)
通过T
类中的deconstruction implementation,您可以使用元组访问实例字段。您需要在T
类中提供解构实现,以便它为元组获得正确的值。
您可以通过以下方式解决问题:
在T
班级中提供解构实施,假设T
为TestClass
public class TestClass
{
private int _first { get; set; }
private int _second { get; set; }
private int _third { get; set; }
public TestClass(int first, int second, int third)
{
_first = first;
_second = second;
_third = third;
}
// Implementation for tuple deconstruct
public void Deconstruct(out int first, out int second)
{
first = _first;
second = _second;
}
}
在Foo
方法中,您可以通过以下方式访问:
public class Bar
{
public void Foo<T>(T data) where T : TestClass
{
(int first, int second) = data;
//do stuff with tuples
}
}
答案 1 :(得分:4)
元组值名称不会附加到实例,而是附加到函数的变量,参数或返回值。
这是所有有效的C#代码:
(int a, string bx) M((int x, string y) p) => p;
// ..
(int i, string s) v1 = (j:1, k:"ome");
(int m, string n) v2 = M(v1);
对于运行时,真正重要的是元组的类型(在上面的例子中总是ValueTuple<int, string>
)。名称只是提供给代码读者的工具便利。
答案 2 :(得分:1)
你不能使用名字&#34;首先&#34;和&#34;第二&#34;在Foo方法中。 但你可以使用bar.Item1或bar.Item2。
共鸣是名字&#34; first&#34;和&#34;第二&#34;不存在 - 它只是语法的原型。编译器在这里接受第一个和第二个 - 但它仍然是一个ValueTuple
答案 3 :(得分:1)
无论如何我可以将myTuple传递给Foo,它会保持元组内元素的命名,这样我就能做类似bar.firstValue的事情吗?
泛型方法的实现不是(也不应该)依赖于您作为参数传递的参数。所以T
可以是任何东西。值类型或引用类型。
约束只能将泛型类型限制为更具体的类型。你怎么不能为ValueTuple声明约束。
如果你想实现一些适用于元组的东西,那么你需要实际的元组作为参数。不是通用类型。