이니셜 라이저 표현식의 두 가지 변형의 차이점은 무엇입니까?

Tagc 09/16/2017. 1 answers, 803 views
c# collection-initializer

나는 C #을 잠시 사용 해왔다.하지만 최근에 단위 테스트 중 하나의 동작이 내가 사용했던 콜렉션 이니셜 라이저 표현의 변형에 따라 달라지는 것을 발견했다.

  • var object = new Class { SomeCollection = new List { 1, 2, 3 } };
  • var object = new Class { SomeCollection = { 1, 2, 3 } };

이 시점까지 나는 두 번째 형태가 단지 통사론적인 설탕이고 의미 론적으로 첫 번째 형태와 동일하다고 가정했다. 그러나이 두 형식 사이를 전환하면 실패한 단위 테스트를 통과하게됩니다.

아래의 예제 코드에서는이를 보여줍니다.

 void Main()
{
    var foo1 = new Foo { Items = new List { 1, 2, 3} };
    var foo2 = new Foo { Items = { 1, 2, 3 } };

    foo1.Dump();
    foo2.Dump();
}

class Foo
{
    public List Items { get; set; }
} 

이걸 실행하면 첫 번째 할당은 제대로 작동하지만 두 번째 결과는 NullReferenceException 됩니다.

내 직감은 뒤에서 컴파일러가이 두 표현식을 다음과 같이 취급한다는 것입니다.

 var foo1 = new Foo();
foo1.Items = new List { 1, 2, 3 }; 

var foo2 = new Foo();
foo2.Items.Add(1);
foo2.Items.Add(2);
foo2.Items.Add(3); 

그 가정은 정확합니까?

1 Comments
Leon Barkan 07/31/2017
그러면 도움이 될 것입니다 : c-sharpcorner.com/article/...

1 Answers


Jon Skeet 07/31/2017.

예, 귀하의 가정은 정확합니다. 객체 이니셜 라이저에 다음이있는 경우 :

{
    Property = { ... }
} 

오히려

{
    Property = expression
} 

속성에 대한 setter 가 사용되지 않습니다. getter 가 사용 된 다음 Add 메서드가 호출되거나 반환 된 값 내에 속성이 설정됩니다. 그래서:

var foo = new Foo
{
    Collection = { 1 }
    Property =
    {
        Value = 1
    }
}; 

다음과 같습니다.

// Only the *getters* for Collection and Property are called
var foo = new Foo();
foo.Collection.Add(1);
foo.Property.Value = 1; 

그것을 다음과 비교하십시오 :

var foo = new Foo
{
    Collection = new List { 1 },
    Property = new Bar { Value = 1 }
}; 

이는 다음과 같습니다.

// The setters for Collection and Property are called
var foo = new Foo();
foo.Collection = new List { 1 };
foo.Property = new Bar { Value = 1 }; 
1 comments
1 Ash Burlaczenko 07/31/2017
새로운 컬렉션과 동등하지 않아야합니까? 아니면 그냥 추가할까요?

Related questions

Hot questions

Language

Popular Tags