programing tip

C #의 식에서 new Object ()와 new Object {}의 차이점은 무엇입니까?

itbloger 2020. 11. 18. 08:37
반응형

C #의 식에서 new Object ()와 new Object {}의 차이점은 무엇입니까?


다음 코드 스 니펫이 있습니다.

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();

일반 원시 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.

그러나 초기화 표현식을 사용하는 것은 .NET에서 공용 속성 또는 필드의 값을 설정하려고하기 때문입니다 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" };

귀하의 경우 클래스에는 매개 변수가없는 생성자가 있으므로 구두점 {, }이나 연산자 모두 ()괜찮습니다.

For simple scenarios where you have a parameterless constructor, you can use only the TDest() short form.

But if you had for example the below class.

class TDest
{
    readonly ISomeInterface _someService;

    public string MyProperty { get; set; }

    public TDest(ISomeInterface someService)
    {
        _someService = someService;
    }
}

And you wanted to initialize MyProperty with something rather than its default initialization value (null, reference types), you could use the full object initialization. E.g.:

// Sample 3
new TDest(new MySomeServiceImplementation()) { MyProperty = "This is the value of my property" };

Hopefully it helps!

To have a better idea, go and have a look at C# Object Initializers.

참고URL : https://stackoverflow.com/questions/49734290/what-is-the-difference-between-new-object-and-new-object-in-expressions-in-c

반응형