2010-01-07 56 views
29

Tôi thích initializer cú pháp C# 3 và sử dụng nó rất nhiều, nhưng hôm nay khi nhìn trong Reflector, sau đây đã đưa ra:Initializer cú pháp

var binding = new WSHttpBinding 
{ 
    ReaderQuotas = { MaxArrayLength = 100000 }, 
    MaxReceivedMessageSize = 10485760 
}; 

Lúc đầu, tôi nghĩ đó là một sai lầm, nhưng nó biên dịch ! Đoán tôi vẫn đang học những thứ mới mọi lúc. :)

Từ những gì tôi có thể biết, nó đặt thuộc tính MaxArrayLength của thuộc tính ReaderQuotas của WSHttpBinding.

Cú pháp này có tạo đối tượng ReaderQuotas mới và sau đó đặt thuộc tính hoặc nó có giả định thuộc tính được khởi tạo không? Đây có phải là cách chung mà người ta sẽ sử dụng để khởi tạo các thuộc tính 'con'?

tôi không tìm thấy cú pháp một chút bối rối ...

+0

Bạn có thể quan tâm đến [bài đăng này] (http: //www.codeducky.org/even-concise-c-object-initializers /), thảo luận về ngữ nghĩa và trường hợp sử dụng cho kiểu khởi tạo này – ChaseMedallion

Trả lời

22

Không, điều đó không tạo ra các đối tượng mới, trừ khi bạn sử dụng = new SomeType {...}:

var binding = new WSHttpBinding 
{ 
    ReaderQuotas = new XmlDictionaryReaderQuotas { MaxArrayLength = 100000 }, 
    MaxReceivedMessageSize = 10485760 
}; 

dụ của bạn cho thấy cú pháp khởi tạo để thiết lập thuộc tính của hiện có các đối tượng phụ. Cũng có một cú pháp tương tự để gọi các phương thức "Thêm" trên các bộ sưu tập.

Mã của bạn là rộng rãi so sánh với:

var binding = new WSHttpBinding(); 
binding.ReaderQuotas.MaxArrayLength = 100000; 
binding.MaxReceivedMessageSize = 10485760; 
+0

Trông giống như vậy, có nhiều hơn một sự khác biệt về cú pháp không? Hình như mặc dù (trừ khi ReaderQuotas được khởi tạo trong contructor của WSHttpBinding) nó nên ném một ngoại lệ – James

+0

Cảm ơn, nó chỉ mất tôi bởi bất ngờ :) Tôi giả sử bằng cách 'Thêm' bạn có nghĩa là như một bộ khởi tạo bộ sưu tập? – leppie

+0

@james: Tôi sẽ mong đợi một ngoại lệ trong trường hợp đó, nhưng không có mã nguồn có thể chứng minh khó hiểu, nếu bạn không biết những gì được thực hiện trong constructor. Một số quá tải khởi tạo có thể hoặc không thể khởi tạo thuộc tính đó, điều này sẽ dẫn đến sự nhầm lẫn nhiều hơn nữa. – leppie

14

Đó là một chút bối rối, tôi đồng ý.

Bạn nên đọc phần 7.6.10.2 của đặc điểm kỹ thuật; tất cả được giải thích là ở đó. Ví dụ:

Một initializer thành viên mà xác định một biểu thức sau dấu bằng được xử lý theo cách tương tự như một bài tập đến lĩnh vực hay tài sản.

Một initializer thành viên đó xác định một initializer đối tượng sau equals dấu là một initializer đối tượng lồng nhau, nghĩa là một sự khởi của một nhúng đối tượng. Thay vì chỉ định giá trị mới cho trường hoặc thuộc tính, các bài tập trong đối tượng lồng nhau trình khởi tạo được coi là bài tập cho thành viên của trường hoặc thuộc tính. Trình khởi tạo đối tượng lồng nhau không được áp dụng cho các thuộc tính có giá trị loại hoặc tới các trường chỉ đọc có loại giá trị .

Trình khởi tạo thành viên chỉ định trình khởi tạo bộ sưu tập sau bằng dấu là khởi tạo bộ sưu tập được nhúng . Thay vì chỉ định bộ sưu tập mới cho trường hoặc thuộc tính , các phần tử được cung cấp trong bộ khởi tạo được thêm vào bộ sưu tập được tham chiếu bởi trường hoặc thuộc tính .