2017-07-31 13 views
20

Tôi đã sử dụng C# một thời gian, nhưng thời gian gần đây nhận thấy rằng các hành vi của một trong những đơn vị xét nghiệm của tôi thay đổi tùy thuộc vào biến thể của bộ sưu tập initialiser biểu tôi đã sử dụng:Sự khác biệt giữa hai biến thể của các biểu thức khởi tạo bộ sưu tập này là gì?

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

Cho đến thời điểm này, tôi giả định rằng biểu mẫu thứ hai chỉ là cú pháp và tương đương ngữ nghĩa với dạng đầu tiên. Tuy nhiên, việc chuyển đổi giữa hai biểu mẫu này dẫn đến việc kiểm tra đơn vị bị lỗi của tôi đi qua.

Các mã ví dụ dưới đây minh chứng điều này:

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

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

class Foo 
{ 
    public List<int> Items { get; set; } 
} 

Khi tôi chạy này, nhiệm vụ đầu tiên hoạt động tốt nhưng kết quả thứ hai trong một NullReferenceException.

cảm giác ruột của tôi là đằng sau hậu trường trình biên dịch được điều trị hai biểu thức như thế này:

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

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

Đó là giả định chính xác?

+0

Điều đó sẽ giúp bạn: http://www.c-sharpcorner.com/article/C-Sharp-heaping-vs-stacking-in-net-part-iii/ –

Trả lời

22

Vâng, giả định của bạn là chính xác. Nếu một đối tượng khởi tạo chỉ có:

{ 
    Property = { ... } 
} 

hơn

{ 
    Property = expression 
} 

thì setter cho bất động sản không được sử dụng - các getter được sử dụng, và sau đó một trong hai phương pháp Add là được gọi, hoặc các thuộc tính được đặt trong giá trị trả lại. Vì vậy:

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

tương đương với:

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

Hãy so sánh điều đó với:

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

tương đương với:

// The setters for Collection and Property are called 
var foo = new Foo(); 
foo.Collection = new List<int> { 1 }; 
foo.Property = new Bar { Value = 1 }; 
+1

Không nên tương đương với bộ sưu tập mới hay nó chỉ thêm vào? –

Các vấn đề liên quan