我可以将ValueTuple传递给需要泛型类型并仍然维护成员变量的方法吗?

时间:2017-10-20 14:04:27

标签: c# tuples valuetuple

以下只是一个关于语言本身的问题,在开始构建我的代码之前,我开始考虑这个问题,但它让我感兴趣。

如果我有这种结构的方法

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之类的事情了吗?

4 个答案:

答案 0 :(得分:5)

通过T类中的deconstruction implementation,您可以使用元组访问实例字段。您需要在T类中提供解构实现,以便它为元组获得正确的值。

您可以通过以下方式解决问题:

  1. T班级中提供解构实施,假设TTestClass

    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;
        }
    
    }
    
  2. 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声明约束。

如果你想实现一些适用于元组的东西,那么你需要实际的元组作为参数。不是通用类型。