Discussion: Deconstruction of anonymous types #244
Replies: 11 comments 8 replies
-
With property patterns you could do that, if ( new { u.Id, u.Name } is { Id: var id, Name: var name } ) However, since this pattern always succeeds, a statement form can help, like dotnet/roslyn#16183 case { Id: var id, Name: var name } = new { u.Id, u.Name }; OR: _ = new { u.Id, u.Name } is { Id: var id, Name: var name }; 😄 |
Beta Was this translation helpful? Give feedback.
-
Implementing this feature sounds like it should be relatively simple. The compiler could emit a var foo = new { X = 123, Y = 456 };
// synthetic class:
public class AnonymousType0<T1, T2> {
public T1 X { get; }
public T2 Y { get; }
public AnonymousType0(T1 X, T2 Y) {
this.X = X;
this.Y = Y;
}
// Equals, GetHashCode, etc.
public void Deconstruct(out T1 X, out T2 Y) {
X = this.X;
Y = this.Y;
}
} |
Beta Was this translation helpful? Give feedback.
-
Type members are unordered, with |
Beta Was this translation helpful? Give feedback.
-
Being simple to implement doesn't imply that it's a good idea. Indeed this relies on an implementation detail of anonymous types that could change in the future. But I don't see any confusion here, at least not any more confusion than when working with tuples. While tuples do somewhat obviate the use cases for something like this it doesn't eliminate them. The use case mentioned in this proposal involves Entity Framework, which to my knowledge does not currently support tuples. That may change, but in the meantime the only option to deconstruct the result of a query like that would be: var (userId, userName) = MyContext.Users
.Select(u => new { u.Id, u.Name })
.AsEnumerable()
.Select(u => (u.Id, u.Name))
.First(); |
Beta Was this translation helpful? Give feedback.
-
I wouldn't say that's the only option. Successive assignment statements (what we've always done) is really not all that horrible or cumbersome here. I worry there is too much effort being spent trying to cram everything into a single expression, regardless of whether it's worth all that design effort (not to mention its questionable whether readability is actually improved). |
Beta Was this translation helpful? Give feedback.
-
Sure, there are many things the developer could do. But to invoke "deconstruction" as defined as the specific operation supported by the compiler would require more code than might be necessary. One could always manually reference the properties and assign variables, as is described in the original post.
My point was only that given the current implementation of anonymous types by the C# compiler that this feature could be implemented with very little effort. It's a valid argument that anonymous types aren't positional like tuples are, but given their locality and their syntax I don't think that's much of an issue. It wouldn't be any less readable than tuples. |
Beta Was this translation helpful? Give feedback.
-
Is there any information on whether a decision was made? If the question is still open, here is a use case that, in fact, brought me here. var request = d1.Join(d2,
x => x.Key,
y => y.Key,
(x, y) => new {x.Key, Left = x.Value, Right = y.Value}); This should produce an
Anonymous types respect the names and order of their properties, so can a void AnnonymousType_01.Deconstruct(out string key, out T1 left, out T2 right)
=> (key, left, right) = (this.Key, this.Left, this.Right); following my dictionary join example. foreach(var (_, left, right) in request)
{
// Do things
} This is possible if the join operation is materialized into |
Beta Was this translation helpful? Give feedback.
-
@jcouv Interesting proposal. Given that anonymous types are ordered, it actually does seem like we could make some sort of conversion between them and tuples :) |
Beta Was this translation helpful? Give feedback.
-
Sure... you could do this, but why not just write:
The anonymous type just seems like unnecessary intermediary steps (not to mention allocations). |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi, I agree that tuples are much easier to deal with, but anonymous types were there long before Assuming that anonymous types can still be used somewhere, it could be nice to have a I am not saying that this should be implemented because it requires an introduction of a new instance method on all generated anonymous types, I was just surprised to find this discussion still open and with no decision made. |
Beta Was this translation helpful? Give feedback.
-
I meant to say expression trees:
dotnet/roslyn#16995
…On Mon, Mar 13, 2023 at 9:40 AM David Arno ***@***.***> wrote:
@DaveVdE <https://github.com/DaveVdE>,
You can't use tuples in an expression.
The compiler disagrees with you
<https://sharplab.io/#v2:EYLgtghglgdgNAFxAJwK7wCYgNQB8ACATAIwCwAUPgAwAE+xAdADKwCOA3BdXcQCyfkKANwjIaGYjQC8NGAFMA7jQAiUAMYIoAexiiAngB56VODVgIAfBQDeFGvZoBtAEQRnAXWk1icOw5fAHl6EFAC+AsKi4oRe8kqqGtq6yIbGpuYWABQAlDQ2fvYBQTLEJgVOzmrFNIRUYRHkImLIcqyocgDOCF4SDABSWrCZGIS+5A40AB7SFlMMANJyeqblejM0egtLK+MOmZOmerlSs/tbyzRMcgBmSHMAahAANu2mAEpQAOYAFnebjy85Nlsg1rloWhA1N9Mk0zAg5GAzDAaC02p0ENl8rt7PQAJyZAAkzmsUHhYHOoVMJLJzBuCEpNGpCIYHx+9OcILCQA==>
—
Reply to this email directly, view it on GitHub
<#244 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAE64CCCGZ753EQ53DYOQDTW33MQ7ANCNFSM5DYJHCDA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
A useful feature would be deconstruction of anonymous types,. Given the following common pattern for extracting projections from LINQ:
It would be nice to do the following:
The order of the variables would be the same as the order of the declarations in the anonymous type. Alternatively, one could name them if one wanted another order:
Of course, one would have to handle cases like
.FirstOrDefault()
, which might make every deconstructed variable nullable.Beta Was this translation helpful? Give feedback.
All reactions