MSDN khẳng định rằng:Sự khác biệt giữa Collection Initializer Câu lệnh
Bằng cách sử dụng một initializer bộ sưu tập bạn không cần phải xác định nhiều cuộc gọi đến các phương thức Add của lớp trong mã nguồn của bạn; trình biên dịch thêm các cuộc gọi.
Họ cũng đưa ra ví dụ này, bằng cách sử dụng cú pháp khởi tạo bộ sưu tập mới với dấu ngoặc:
var numbers = new Dictionary<int, string> {
[7] = "seven",
[9] = "nine",
[13] = "thirteen"
};
Tuy nhiên, khi kiểm tra mã IL được tạo ra, có vẻ như rằng mã này không ở tất cả các kết quả trong bất kỳ cuộc gọi với phương pháp Add
, nhưng để thay cho một set_item
, như vậy:
IL_0007: ldstr "seven"
IL_000c: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::set_Item(!0/*int32*/, !1/*string*/)
các "cũ" cú pháp với dấu ngoặc nhọn trong tương phản cho những điều sau đây:
// C# code:
var numbers2 = new Dictionary<Int32, String>
{
{7, "seven"},
{9, "nine"},
{13, "thirteen"}
};
// IL code snippet:
// ----------
// IL_0033: ldstr "seven"
// IL_0038: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::Add(!0/*int32*/, !1/*string*/)
... Như bạn có thể thấy, gọi tới số Add
là kết quả như mong đợi. (Người ta chỉ có thể giả định rằng văn bản trên MSDN được đề cập ở trên vẫn chưa được cập nhật.)
Tôi đã phát hiện ra một trường hợp sự khác biệt này thực sự quan trọng, và đó là với kỳ quặc System.Collections.Specialized.NameValueCollection
. Điều này cho phép một khóa trỏ đến nhiều hơn một giá trị. Khởi tạo có thể được thực hiện trong cả hai cách:
const String key = "sameKey";
const String value1 = "value1";
const String value2 = "value2";
var collection1 = new NameValueCollection
{
{key, value1},
{key, value2}
};
var collection2 = new NameValueCollection
{
[key] = value1,
[key] = value2
};
... Nhưng vì sự khác biệt về chỉ cách cựu thực sự gọi là NameValueCollection::Add(string, string)
, kết quả khác nhau khi nhìn vào nội dung của từng bộ sưu tập;
collection1 [key] = "value1, value2"
collection2 [key] = "value2"
tôi nhận ra rằng có một mối liên hệ giữa cú pháp cũ và giao diện IEnumerable
, và cách trình biên dịch tìm phương thức Add
bằng cách đặt tên quy ước etcetera. Tôi allso nhận ra những lợi ích của bất kỳ loại indexer đang phải chịu cú pháp mới, như đã thảo luận trong this SO answer trước đây.
Có lẽ đây là tất cả các tính năng được mong đợi, từ quan điểm của bạn, nhưng các tác động đã không xảy ra với tôi và tôi rất tò mò muốn biết thêm.
Vì vậy, tôi tự hỏi nếu có nguồn tài liệu tại MSDN hoặc ở nơi khác làm rõ sự khác biệt này trong hành vi đi kèm với lựa chọn cú pháp. Tôi cũng tự hỏi nếu bạn biết về bất kỳ ví dụ khác, nơi sự lựa chọn này có thể có tác động như khi khởi tạo một NameValueCollection
.
Các tài liệu bạn tham khảo để làm nói điều này trên cú pháp 'mới': * Bạn có thể chỉ định các yếu tố được lập chỉ mục nếu bộ sưu tập hỗ trợ lập chỉ mục. *. Với tôi, điều đó ngụ ý nó sẽ sử dụng bộ chỉ mục để thực hiện cài đặt. –
@CharlesMager Tôi sắp sửa đăng một nội dung tương tự sau khi nhìn thấy [this] (http://stackoverflow.com/questions/28076127/c6s-new-collection-initializer-clarification) – Rawling
@CharlesMager Đúng là những gì bạn nói, nhưng tôi 'd hầu như không gọi đó là một "làm sáng tỏ", có lẽ tiết kiệm cho người đã giác ngộ;) Ngoài ra, câu hỏi - theo như sự khác biệt trong hành vi đi - rõ ràng chỉ áp dụng cho các loại chịu sự "lập chỉ mục" và "thêm", cái gì đó cũng không được thảo luận trên trang đó. –