我可以将 ValueTuple 传递给需要泛型类型的方法并仍然维护成员变量吗?
Can I pass a ValueTuple to a method that requires a generic type and still maintain the member variables?
以下只是关于语言本身的问题,在发布构建我的代码的更好方法之前,我开始考虑这个问题,但它引起了我的兴趣。
如果我有这种结构的方法
private void Foo<T>(T bar){
//do stuff with tuples
}
并且在不同的 class 和方法中,我有一个变量
(int first, int second) myTuple = (1,2);
在这个变量的范围内,我可以做类似的事情
var firstValue = myTuple.first;
我是否可以将 myTuple
向下传递给 Foo
,这将维护元组中元素的命名,以便我可以执行类似 bar.firstValue
的操作?
您不能在 Foo 方法中使用名称 "first" 和 "second"。
但您可以使用 bar.Item1 或 bar.Item2.
原因是名称 "first" 和 "second" 并不真正存在 - 它只是句法 sougar。编译器在这里接受 first 和 second - 但它仍然是一个 ValueTuple
Is there anyway I could pass myTuple down to Foo which would maintain the naming of elements within the tuple so that I could do something like bar.firstValue?
泛型方法的实现不(也不应该)取决于您作为参数传递的参数。所以 T
可以是任何东西。值类型或引用类型。
约束只能将通用类型限制为更具体的类型。你怎么不能为 ValueTuple 声明约束。
如果你想实现一些对元组起作用的东西,那么你需要实际的元组作为参数。不是通用类型。
通过deconstruction implementation in T
class,您可以使用元组访问实例字段。您需要在 T
class 中提供解构实现,以便它将获得元组的正确值。
您可以通过以下方式解决您的问题:
在T
class中提供解构实现,假设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
}
}
元组值名称不附加到实例,而是附加到函数的变量、参数或 return。
这都是有效的 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>
)。这些名称只是为代码 reader 提供的工具便利。
以下只是关于语言本身的问题,在发布构建我的代码的更好方法之前,我开始考虑这个问题,但它引起了我的兴趣。
如果我有这种结构的方法
private void Foo<T>(T bar){
//do stuff with tuples
}
并且在不同的 class 和方法中,我有一个变量
(int first, int second) myTuple = (1,2);
在这个变量的范围内,我可以做类似的事情
var firstValue = myTuple.first;
我是否可以将 myTuple
向下传递给 Foo
,这将维护元组中元素的命名,以便我可以执行类似 bar.firstValue
的操作?
您不能在 Foo 方法中使用名称 "first" 和 "second"。 但您可以使用 bar.Item1 或 bar.Item2.
原因是名称 "first" 和 "second" 并不真正存在 - 它只是句法 sougar。编译器在这里接受 first 和 second - 但它仍然是一个 ValueTuple
Is there anyway I could pass myTuple down to Foo which would maintain the naming of elements within the tuple so that I could do something like bar.firstValue?
泛型方法的实现不(也不应该)取决于您作为参数传递的参数。所以 T
可以是任何东西。值类型或引用类型。
约束只能将通用类型限制为更具体的类型。你怎么不能为 ValueTuple 声明约束。
如果你想实现一些对元组起作用的东西,那么你需要实际的元组作为参数。不是通用类型。
通过deconstruction implementation in T
class,您可以使用元组访问实例字段。您需要在 T
class 中提供解构实现,以便它将获得元组的正确值。
您可以通过以下方式解决您的问题:
在
T
class中提供解构实现,假设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 } }
元组值名称不附加到实例,而是附加到函数的变量、参数或 return。
这都是有效的 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>
)。这些名称只是为代码 reader 提供的工具便利。