2012-02-24 28 views
20

Ive chỉ nhìn thấy một đoạn mã có sử dụng một lớp danh sách chung để nhanh chóng tự theo cách sau đây:Cú pháp này bằng cách sử dụng mới theo sau bởi một danh sách bên trong niềng răng là gì?

var foo = new List<string>(){"hello", "goodbye"}; 

Các dấu ngoặc nhọn sau khi contructor đặc biệt khó hiểu. Nó nhắc nhở tôi hơi của

var bar = new string[]{"hi","bye"}; 

nhưng trong quá khứ tôi đã wouldve luôn được sử dụng:

var foo = new List<string>(new []{"hello", "goodbye"}); 

Có ai có một liên kết để giải thích cú pháp trong dòng đầu tiên của mã? Tôi thậm chí sẽ không biết bắt đầu từ đâu với googling nó.

+36

Cú pháp "khó hiểu" ngay lập tức nhắc bạn về tính năng * giống hệt cho mảng * có khả năng là dấu hiệu cho thấy nó thực sự không gây nhầm lẫn chút nào, phải không? Chúng tôi đã chọn cú pháp đó rất cẩn thận để nó có thể dẫn bạn đến chính xác trực giác mà bạn đã có. –

+0

@maxp "Trong quá khứ", bạn đã khởi tạo một Danh sách bằng cách gọi một hàm tạo mất IEnumerable và sử dụng cú pháp khởi tạo mảng để tạo một bộ sưu tập ẩn danh, tạo hai tham chiếu đến cùng một bộ sưu tập. TBH Tôi không biết tại sao trình biên dịch không tối ưu hóa cú pháp trong dòng 1 đến dòng 3 - chắc chắn nó biết rằng đối tượng được tạo ra bởi 'new []' được chuyển vào hàm tạo List không thể được gọi độc lập theo bất kỳ cách nào khác, và do đó không cần thiết để tiếp tục sống. –

+7

@ValAkkapeddi: Nhóm biên dịch * nên biết người viết 'List 'sẽ làm gì với đối tượng đó? Trình biên dịch không có kiến ​​thức đặc biệt mà bất kỳ công cụ 'List ' cụ thể nào có hoặc không làm bất cứ điều gì đặc biệt với mảng được truyền cho nó. –

Trả lời

30

thông tin cho bạn đây. Từ khóa là "Array Initializers".

http://msdn.microsoft.com/en-us/library/aa664573(v=vs.71).aspx

hay đúng hơn là "Bộ sưu tập Initializers"

http://msdn.microsoft.com/en-us/library/bb384062.aspx

+1

Cảm ơn. Tôi thấy rằng các bộ khởi tạo bộ sưu tập này là chuẩn trên bất kỳ lớp nào thực hiện 'iEnumerable.' – maxp

+0

nội dung cộng đồng trên liên kết thứ hai thảo luận về một chút ... không thể xác nhận ... chờ, vâng, có thể nói trong tài liệu. – mindandmedia

+3

@ maxp không đúng. Trình biên dịch chuyển đổi bộ khởi tạo bộ sưu tập thành các cuộc gọi đến phương thức Thêm của loại (xem câu trả lời của tôi để biết thêm chi tiết). Một loại có thể thực hiện IEnumerable mà không cần có phương thức Thêm; bộ khởi tạo bộ sưu tập không thể được sử dụng với loại đó. Ví dụ, 'System.String' thực hiện IEnumerable, nhưng không có phương thức' Add'. – phoog

16

Đây là một initializer bộ sưu tập: http://msdn.microsoft.com/en-us/library/bb384062.aspx

Loại để khởi tạo phải thực hiện IEnumerable và có một phương pháp Add. Các mục trong danh sách ngoặc nhọn được chuyển đến phương thức thêm; các mục khác nhau trong danh sách có thể được chuyển đến các phương thức Add khác nhau. Nếu có quá tải Add với nhiều hơn một đối số, bạn đặt nhiều đối số trong danh sách được phân tách bằng dấu phẩy được bao quanh trong dấu ngoặc nhọn.

Ví dụ:

class MyWeirdCollection : IEnumerable 
{ 
    public void Add(int i) { /*...*/ } 
    public void Add(string s) { /*...*/ } 
    public void Add(int i, string s) { /*...*/ } 

    //IEnumerable implementation omitted for brevity 
} 

Lớp này có thể được khởi tạo như sau:

var weird = new MyWeirdCollection { 1, "Something", {5, "Something else"} }; 

này biên dịch một cái gì đó như thế này:

var temp = new MyWeirdCollection(); 
temp.Add(1); 
temp.Add("Something"); 
temp.Add(5, "Something else"); 
var weird = temp; 

Trong his blog post (liên kết được đăng bởi Eric Lippert trong các ý kiến), Mads Torgersen thể hiện điều này một cách chính xác:

Danh sách bạn cung cấp không phải là “danh sách các phần tử cần thêm”, mà là “danh sách các bộ đối số để thêm phương thức”. ... [W] e thực hiện phân giải quá tải riêng biệt so với Thêm phương thức cho mỗi mục nhập trong danh sách.

+0

+1 Đây là một ví dụ tuyệt vời! – dasblinkenlight

+0

Mã này sẽ không biên dịch. 'Không thể khởi tạo loại 'MyWeirdCollection' với bộ khởi tạo bộ sưu tập vì nó không triển khai 'System.Collections.IEnumerable' – maxp

+0

phiên bản C# này là gì? – mindandmedia

2

Đây là collection initializer. Bạn có thể sử dụng nó trên các bộ sưu tập với phương thức Add.

Cặp dấu ngoặc đơn trước dấu ngoặc nhọn là tùy chọn.

này rất thuận lợi, bởi vì bạn có thể sử dụng nó trên các bộ sưu tập khác ngoài danh sách, ví dụ về các từ điển:

var x = new Dictionary<int,string> {{1, "hello"}, {2, "world"}}; 

này cho phép bạn tránh được một chuỗi khởi tạo dài hơn:

var x = new Dictionary<int,string>(); 
x.Add(1, "hello"); 
x.Add(2, "world"); 
2

Trong dòng thứ ba của mã bạn cung cấp, bạn đang tạo một mảng chuỗi mới, và sau đó chuyển mảng chuỗi đó vào danh sách. Danh sách sau đó sẽ thêm từng mục đó vào danh sách. Điều này liên quan đến chi phí bổ sung của phân bổ mảng, điền vào nó, và sau đó loại bỏ nó.

Có cơ chế cho lớp học để xác định cách sử dụng Trình tạo tập hợp để tự điền. (Xem các câu trả lời khác) Tôi chưa bao giờ thấy cần phải sử dụng điều này cho các lớp của riêng tôi, nhưng các cấu trúc dữ liệu hiện có như Danh sách, Từ điển, thường xác định chúng, và chúng hữu ích khi sử dụng.

36

Như những người khác đã chỉ ra, đó là bộ khởi tạo bộ sưu tập. Một số tính năng khác mà bạn có thể không biết được đã được thêm vào C# 3:

  • Trình tạo bộ tạo khởi tạo bộ sưu tập có thể bỏ qua dấu ngoặc đơn nếu danh sách đối số trống. Vì vậy, new List<int> { 10, 20, 30 } là tốt.
  • Một mảng được khởi tạo với bộ khởi tạo mảng có thể trong một số trường hợp bỏ qua loại. Ví dụ: var myInts = new[] { 10, 20, 30}; infers rằng myIntsint[].
  • Đối tượng có thể được khởi tạo bằng cách sử dụng cú pháp khởi tạo đối tượng tương tự. var c = new Customer() { Name = "Fred" }; giống với var temp = new Customer(); temp.Name = "Fred"; var c = temp;

Điểm của các tính năng này là (1) thực hiện nhiều điều được sử dụng để yêu cầu câu lệnh thành những thứ chỉ yêu cầu biểu thức; LINQ thích những thứ phải là biểu thức, và (2) để cho phép suy luận kiểu phong phú hơn, đặc biệt cho các kiểu ẩn danh.

Cuối cùng: đã có một số nhầm lẫn trong một số câu trả lời và nhận xét về những gì được yêu cầu cho bộ khởi tạo bộ sưu tập. Để được sử dụng với bộ khởi tạo bộ sưu tập, loại phải (1) thực hiện IEnumerable (để chúng tôi biết đó là bộ sưu tập) và (2) có phương thức Add (để chúng tôi có thể thêm công cụ vào nó.)

Xem

http://blogs.msdn.com/b/madst/archive/2006/10/10/what-is-a-collection_3f00_.aspx

để có thêm suy nghĩ về thiết kế đối tượng địa lý.

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