C# 7:How can I deconstruct an object into a single value using a tuple?

不羁的心 提交于 2019-12-01 01:15:30

问题


One of the nice new features of C# 7 is the possibility to define deconstructors for classes and assign the deconstructed values directly to a value tuple.

However, in the case that the object is deconstructed into a single value, I can't find a way to assign it to a tuple. Although there is a type for tuples with a single element (ValueTuple<T>), the shorthand syntax using parentheses doesn't work here. The only way I found to access the deconstructor was to call the Deconstruct method directly, but this eliminates its benefit, as I could use any method for this end.

Does anyone know a better way to deconstruct an object into a single value?

Here is my test code:

class TestClass
{
    private string s;
    private int n;
    public TestClass(string s, int n) => (this.s, this.n) = (s, n);
    public void Deconstruct(out string s) => s = this.s;
    public void Deconstruct(out string s, out int n) => (s, n) = (this.s, this.n);
}

static void Main(string[] args)
{
    var testObject = new TestClass("abc", 3);

    var (s1) = testObject; // sytax error (comma expected)
    ValueTuple<string> t = testObject; // error: "no implicit conversion from TestClass to (string)"
    testObject.Deconstruct(out string s2); // this works
    var (s3, n) = testObject; // no problem

    Console.WriteLine($"{s1} {t.Item1} {s2} {s3} {n}");
    Console.ReadKey();
}

回答1:


Although there is a type for tuples with a single element (ValueTuple<T>), the shorthand syntax using parentheses doesn't work here.

That's correct. The tuple syntax only works for tuples of 2 values or more, so the Deconstruct method with only one out parameter is not very useful. (There is even a ValueTuple type for 0 elements)

The shortest solution is to just ignore the 2nd parameter:

var (s1, _) = testObject;

Edit: based on comments, a little clarification.
As of C# 7, _ is no longer a variable in this situation. It is a new feature called 'discard'.
Even if you have multiple out parameters (and even if they are different types) you can ignore any of them with an underscore:

var (s1, _, _, _) = testObject;



回答2:


Deconstructions into a single element are not supported in C# 7.0.

It is unclear why you would need such a mechanism, as you can simply access a property or write a conversion operator to achieve the same thing.

Conceptually, a tuple of one element is just that one element (you don't need a tuple to hold it). So there is no tuple syntax (using parentheses notation) to facilitate that (not to mention it would be syntactically ambiguous). The same applies for deconstructions.

Here are the most relevant LDM notes I could find: 2017-03-15 (zero and one element tuples and deconstructions).

It is possible that such deconstruction could become allowed in some future recursive pattern scenarios, but that has not been finalized yet.



来源:https://stackoverflow.com/questions/44975958/c-sharp-7how-can-i-deconstruct-an-object-into-a-single-value-using-a-tuple

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!