以下只是一个关于语言本身的问题,在发布更好的代码架构方法之前,我开始考虑这个问题,但它引起了我的兴趣。
如果我有这种结构的方法
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
的事情?
通过在类中解构实现T
可以使用元组访问实例字段。您需要在类中提供解构实现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 } }
组值名称不附加到实例,而是附加到函数的变量、参数或返回。
这是所有有效的 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>
元组)。这些名称只是提供给代码阅读器的工具便利。
在Foo方法中使用名称"first"和"second"。但是你可以使用酒吧。项目 1 或条形图。项目2.
reson 是名称"第一"和"第二"实际上并不存在 - 它只是句法 sougar 。 编译器在这里接受第一个和第二个 - 但它仍然是一个 ValueTuple
无论如何,我可以将myTuple传递给Foo,它将保持元组中元素的命名,以便我可以做类似bar.firstValue的事情?
泛型方法的实现不(也不应该)依赖于作为参数传递的参数。 所以T
可以是任何东西。 值类型或引用类型。
约束只能将泛型类型限制为更具体的类型。 你怎么不能为值元组声明约束。
如果你想实现一些适用于元组的东西,那么你需要实际的元组作为参数。 不是泛型类型。