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();
}
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;
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With