Sự khác nhau 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ì?

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

Tôi đã sử dụng C # trong một thời gian, nhưng gần đây nhận thấy rằng hành vi của một trong các bài kiểm tra đơn vị của tôi đã thay đổi tùy thuộc vào biến thể của biểu thức khởi tạo bộ sưu tập mà tôi đã sử dụng:

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

Cho đến thời điểm này, tôi cho rằng dạng thứ hai chỉ là đường 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.

Mã ví dụ dưới đây minh họa điều này:

 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; }
} 

Khi tôi chạy điều 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 xử lý hai biểu thức này như sau:

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

Giả định đó có chính xác không?

1 Comments
Leon Barkan 31/07/2017
Điều đó sẽ giúp bạn: c-sharpcorner.com/article/…

1 Answers


Jon Skeet 31/07/2017.

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

{
    Property = { ... }
} 

thay vì

{
    Property = expression
} 

sau đó setter cho thuộc tính không được sử dụng - getter được sử dụng, và sau đó hoặc là phương thức Add được gọi, hoặc các thuộc tính được đặt trong giá trị trả về. Vì thế:

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; 

So sánh điều đó với:

var foo = new Foo
{
    Collection = new List { 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 { 1 };
foo.Property = new Bar { Value = 1 }; 
1 comments
1 Ash Burlaczenko 31/07/2017
Không nên tương đương với bộ sưu tập mới hay nó chỉ thêm vào?

Related questions

Hot questions

Language

Popular Tags