В чем разница между new Object() и new Object{} в выражениях в C#
у меня есть следующий фрагмент кода:
Expression<Func<TSource, TDest>> expression = model => new TDest{};
// Result: {model => new TestModel(){}}
ReSharper рефакторинг этот фрагмент с RedundantEmptyObjectOrCollectionInitializer
установка:
Expression<Func<TSource, TDest>> expression2 = model => new TDest();
// Result: {model => new TestModel()}
после этого, мой код не работает. Какое влияние оказывают фигурные скобки на инициализацию?
нашел в чем разница между new object()
и new {}
в C#? при переполнении стека, но оба экземпляра выглядят одинаково.
expression.GetType().ToString()
равна
expression2.GetType().ToString()
в чем разница между этими инициализациями в деревьях выражений?:
var a = model => new TDest{};
var b = model => new TDest();
2 ответа:
в обычном raw C# ответ будет "ничего". Однако, когда вы включаете деревья выражений, есть разница; как видно здесь
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 {}; }
компилируется как:
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); }
так один из них включает в себя
Expression.MemberInit
(С пустым наборомMemberBinding
элементы) в дополнение кExpression.New
. Это может расстроить любого поставщика LINQ (или любой подобный анализ дерева выражений), который этого не ожидает.
ReSharper дает вам лучшее предложение в том, как создать экземпляр
TDest
класса.в теории, нет никакой разницы как
new TDest ()
иnew TDest {}
предоставит вам экземплярTDest
.однако, когда вы используете выражение инициализации, это потому, что вы хотите установить значения свойств или полей
TDest
.class TDest { public string MyProperty { get; set; } }
таким образом, вы можете инициализировать
TDest
класс установка значенияMyProperty
. Например:// Sample 1 new TDest { MyProperty = "This is the value of my property" }; // Sample 2 new TDest() { MyProperty = "This is the value of my property" };
в вашем случае, ваш класс имеет конструктор без параметров, так как знаки пунктуации
{, }
или операторов()
было бы нормально.для простых сценариев, где у вас есть конструктор без параметров, вы можете использовать только
TDest()
короткая форма.но если бы у вас был, например, класс ниже.
class TDest { readonly ISomeInterface _someService; public string MyProperty { get; set; } public TDest(ISomeInterface someService) { _someService = someService; } }
и вы хотели инициализировать
MyProperty
С чем-то, а не его значение инициализации по умолчанию (null, ссылочные типы), вы можете использовать полную инициализацию объекта. Например:// Sample 3 new TDest(new MySomeServiceImplementation()) { MyProperty = "This is the value of my property" };
надеюсь, что это помогает!
чтобы иметь лучшую идею, пойти и посмотреть на Инициализаторы Объектов C#.