2009-04-15 64 views
46

Trong C#, tôi có thể khởi tạo danh sách bằng cú pháp sau.Khởi tạo Generic.List trong C#

List<int> intList= new List<int>() { 1, 2, 3 }; 

Tôi muốn biết cách hoạt động của cú pháp {} và nếu tên đó có tên. Có một hàm tạo có số IEnumerable, bạn có thể gọi nó.

List<int> intList= new List<int>(new int[]{ 1, 2, 3 }); 

Điều đó có vẻ "tiêu chuẩn" hơn. Khi tôi xây dựng cấu trúc mặc định cho Danh sách tôi chỉ thấy

this._items = Array.Empty; 

Tôi muốn có thể thực hiện việc này.

CustomClass abc = new CustomClass() {1, 2, 3}; 

Và có thể sử dụng danh sách 1, 2, 3. Cái này hoạt động ra sao?

Cập nhật

Jon Skeet trả lời

Nó gọi constructor parameterless , và sau đó gọi Địa chỉ:

> List<int> tmp = new List<int>(); 
> tmp.Add(1); tmp.Add(2); tmp.Add(3); 
> List<int> intList = tmp; 

tôi hiểu những gì đang làm. Tôi muốn biết làm thế nào. Cú pháp đó biết cách gọi phương thức Thêm như thế nào?

Cập nhật

Tôi biết, làm thế nào cliche để chấp nhận một câu trả lời Jon Skeet. Nhưng, ví dụ với các chuỗi và ints là tuyệt vời. Cũng là một trang MSDN rất hữu ích là:

Trả lời

64

này được gọi là một initializer bộ sưu tập. Nó gọi constructor parameterless, và sau đó gọi Địa chỉ:

List<int> tmp = new List<int>(); 
tmp.Add(1); 
tmp.Add(2); 
tmp.Add(3); 
List<int> intList = tmp; 

Các yêu cầu cho các loại bao gồm:

  • Nó thực hiện IEnumerable
  • Nó có quá tải của Add mà là thích hợp cho các loại đối số bạn cung cấp. Bạn có thể cung cấp nhiều đối số trong dấu ngoặc ôm, trong trường hợp đó trình biên dịch tìm kiếm phương thức Add với nhiều tham số.

Ví dụ:

public class DummyCollection : IEnumerable 
{ 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     throw new InvalidOperationException("Not a real collection!"); 
    } 

    public void Add(string x) 
    { 
     Console.WriteLine("Called Add(string)"); 
    } 

    public void Add(int x, int y) 
    { 
     Console.WriteLine("Called Add(int, int)"); 
    } 
} 

Sau đó bạn có thể sử dụng:

DummyCollection foo = new DummyCollection 
{ 
    "Hi", 
    "There", 
    { 1, 2 } 
}; 

(Tất nhiên, thông thường bạn muốn sưu tập của bạn để thực hiện IEnumerable đúng ...)

+0

Xấu hổ các đối số là sai đường tròn - nhưng đã được chỉnh sửa ngay bây giờ :) –

+0

Vậy tại sao nó quan tâm đến loại đó là đếm được? nó dường như không thêm bất cứ điều gì khác hơn là làm cho C# nhận thức của NET, tương tự như IDisposable .. làm cho tôi tự hỏi tại sao foreach yêu cầu JUST một chữ ký compat, và không giao diện .. Tôi nghĩ ý tưởng là như vậy C# sẽ không được đặc biệt gắn liền với một 'lang' – meandmycode

+2

@meandmycode: foreach không liên kết với IEnumerable vì trước khi generics không có cách nào khác để lộ một iterator mà không có boxing. Với generics tôi chắc chắn nó sẽ có * chỉ * dựa trên IEnumerable . (Tiếp theo) –

1

Tôi tin rằng đó là lối tắt cho phương thức .Thêm. Tôi đã không bao giờ cố gắng để ghi đè lên nó, mặc dù, vì vậy tôi không biết nếu nó có thể.

+0

Có thể, hãy thử triển khai một IDictionary –

0

Theo như tôi quan tâm, việc thêm các mục thông qua khởi tạo đối tượng sẽ tìm kiếm phương thức Thêm. Vì vậy, như List < int> sẽ có void Add (int), nó sẽ hoạt động.

Để sử dụng nó trong lớp học của bạn, chỉ cần thêm

class CustomClass { 
    public void Add(int num) { 
     // Your code here 
    } 
} 

lớp của bạn nên thực hiện IEnumerable, như Hallgrim chỉ ra.

4

Chúng được gọi là collection initializers (cũng xem here) và cách chúng hoạt động bằng cách tìm kiếm phương thức Add() có thể thực hiện đặt giá thầu của chúng. Nó gọi Add() cho mỗi số nguyên bạn có trong dấu ngoặc nhọn.

Tìm kiếm phương pháp Add() là trình biên dịch ma thuật thuần túy. Đó là hardcoded để tìm một phương pháp của tên đó.

+0

Không chắc chắn nơi bạn đã có từ "mặc định" từ đó - chúng chỉ là "bộ khởi tạo bộ sưu tập". –

+0

Đủ công bằng, tôi đã thay đổi nó. – mquander

2

Tên bạn đang gọi là "Bộ tạo tập lệnh". Nó hoạt động dưới mui xe bằng cách tìm kiếm một phương thức có tên là Add trên loại bộ sưu tập và gọi nó cho mọi giá trị mà bạn chỉ định.

Thông tin chi tiết: Object and Collection Initializers (C# Programming Guide)

0

Nó thực sự sử dụng phương pháp .Add. Có nghĩa là nó gọi .Add cho mỗi mục trong dấu ngoặc bên trong của hàm tạo.