I have the following code snippet:
Expression<Func<TSource, TDest>> expression = model => new TDest{}; // Result: {model => new TestModel(){}}
ReSharper refactors this snippet with RedundantEmptyObjectOrCollectionInitializer
setting:
Expression<Func<TSource, TDest>> expression2 = model => new TDest(); // Result: {model => new TestModel()}
After that, my code doesn't work. What influence do the curly braces have on initializing?
I found What is the Difference Between new object()
and new {}
in C#? on Stack Overflow, but both instances look equal.
expression.GetType().ToString()
is equal to expression2.GetType().ToString()
What is the difference between these initializations in expression trees?:
var a = model => new TDest{}; var b = model => new TDest();
It is used to create objects and invoke a constructor. Using the "new" operator, we can create an object or instantiate an object, in other words with the "new" operator we can invoke a constructor. Let's create a class for example: public class Author.
New-Object creates the object and sets each property value and invokes each method in the order that they appear in the hash table. If the new object is derived from the PSObject class, and you specify a property that does not exist on the object, New-Object adds the specified property to the object as a NoteProperty.
The object type is an alias for System. Object in . NET. In the unified type system of C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from System.
In regular raw C# the answer would be "nothing". However, when you involve expression trees, there is a difference; as can be seen here
using System; using System.Linq.Expressions; public class C<TSource, TDest> where TDest : new() { public Expression<Func<TSource, TDest>> Foo() => model => new TDest(); public Expression<Func<TSource, TDest>> Bar() => model => new TDest {}; }
compiles as:
public Expression<Func<TSource, TDest>> Foo() { ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "model"); Expression arg_2E_0 = Expression.New(typeof(TDest)); ParameterExpression[] expr_2A = new ParameterExpression[1]; expr_2A[0] = parameterExpression; return Expression.Lambda<Func<TSource, TDest>>(arg_2E_0, expr_2A); } public Expression<Func<TSource, TDest>> Bar() { ParameterExpression parameterExpression = Expression.Parameter(typeof(TSource), "model"); Expression arg_38_0 = Expression.MemberInit(Expression.New(typeof(TDest)), Array.Empty<MemberBinding>()); ParameterExpression[] expr_34 = new ParameterExpression[1]; expr_34[0] = parameterExpression; return Expression.Lambda<Func<TSource, TDest>>(arg_38_0, expr_34); }
So one of them involves an Expression.MemberInit
(with an empty set of MemberBinding
elements) in addition to Expression.New
. This can upset any LINQ provider (or any similar expression-tree analysis) that doesn't expect it.
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