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

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

However, if the object is deconstructed into a single value, I cannot find a way to assign it to a tuple. Although there is a type for single-element tuples ( ValueTuple<T> ), shorthand syntax using parentheses does not work here. The only way I found access to the deconstructor was to directly call the Deconstruct method, but this takes away its advantage, since I can use any method for this purpose.

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(); } 
+5
source share
2 answers

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

It is right. The tuple syntax only works for tuples of 2 or more values, so the Deconstruct method with only one out parameter is not very useful. (There is only a ValueTuple type for 0 items)

The shortest solution is to simply ignore the second parameter:

 var (s1, _) = testObject; 

Edit: based on comments, a little clarification.
Starting with C # 7, _ no longer a variable in this situation. This is a new feature called "discard".
Even if you have several options (and even if they are different), you can ignore any of them with an underscore:

 var (s1, _, _, _) = testObject; 
+6
source

Single element demos are not supported in C # 7.0.

It is not clear why you need such a mechanism, because you can simply access the property or write a conversion operator to achieve the same.

In theory, a tuple of one element is only one element (you do not need a tuple to hold it). Thus, there is no tuple syntax (using parentheses) to facilitate this (not to mention syntactically ambiguous). The same thing applies to deconstruction.

Here are the most important LDM notes I can find: 2017-03-15 (zero and one element of tuples and deconstructs).

It is possible that such deconstruction may be allowed in some scenarios of future recursive patterns, but this is not yet complete.

+4
source

Source: https://habr.com/ru/post/1269613/


All Articles