Given a tuple (int, string) v and a class C { int, string }, in C#7, implementing C's Deconstruct(out int k, out string v) would allow the ff.:
C c = new C();
(int k, string v) = c;
But the reverse seems unsupported, such that the tuple can be "reconstructed" to a compatible class:
(int k, string v) vt = (1, "one");
C c = vt;
I'm thinking it should be supported if C has a constructor that "matches" C's Deconstruct() parameters:
class C
{
public C(int k, string v)
...
}
Is it possible? Available? Planned? I can't seem to find anything about it. Or perhaps a re-usable code/trick to "Reconstruct"?
Of course you can. Simply implement an implicit operator:
public static implicit operator C((int, string) t)
=> new C(t.Item1, t.Item2);
There is no need of some special Reconstruct
method because the language already provides the necessary tools to achieve the behavior you want.
There is a very subtle distinction between:
(int, string) x = c; // tuple assignment
(int a, string b) x = c; // tuple assignment with member aliases
and
(int a, string b) = c; // deconstruction
Importantly your code is neither of these, so won't compile - but from the context it is clear that you're talking about deconstruction syntax, so I'm assuming the bottom form.
The deconstruction syntax (the one without a name after the tuple-like expression) doesn't actually create a tuple. In fact, it requires names in the pair:
(int a, string b) = c;
or:
var (a, b) = c;
This is not a tuple, but is convenience syntax for:
c.Deconstruct(out int a, out string b);
So: at no point are tuples involved (although oddly the System.ValueTuple
reference is still required).
The reverse operation - passing multiple variables into a constructor - is: a regular constructor. Note that you couldn't pass the "tuple-like thing" anywhere, because it doesn't have a name - it isn't a local.
There is already a way to do the opposite of deconstructing (ie. taking some object apart to its component elements). It is "constructing" (ie. making an object from components). The most straightforward way to do the opposite of (x, y) = c;
is to do c = new C(x, y);
.
There is a candidate feature that is being considered to simplify syntax like c = new C(x, y);
down to c = new (x, y);
by omitting/inferring the type of the constructor. It's called target-typed construction ([1]).
If you want to propose some other way of constructing, it would be important to show the value of the new feature. The csharplang repo is a good place to discuss such ideas and get a feel for the community and the team's feedback.
Removing the new
may be discussed, but I don't think it's a good idea. For instance, in (x, y, z) = (a, b);
should the compiler consider constructing a type C
from two elements a and b, then invoking the Deconstruct
method with three elements that it may find on C
? You can see how treating deconstructions as conversions (that can chain and appear in a number of places in the code) leads to combinatorial explosion.
[1]: https://github.com/dotnet/csharplang/issues/100 (the link tracks this candidate feature and has a link to most recent LDM notes, which are succinct as the language feature was not discussed in details).
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