2010-05-28 40 views
15

Tôi có thể khởi tạo List<int> like new List<int>{1,2,3,4,5}; Tuy nhiên List<T> không có hàm tạo chấp nhận một thông số duy nhất. Vì vậy, tôi đã cố gắng chạy điều này thông qua trình gỡ lỗi và có vẻ như đang gọi phương thức Thêm. Vậy trình biên dịch biết phương thức nào cần gọi để thêm từng phần tử riêng lẻ.Danh sách <int> khởi tạo trong C# 3.5

Đây có thể là câu hỏi ngớ ngẩn nhưng tôi hơi bối rối.

Cảm ơn

Trả lời

9

Mọi loại có phương thức Thêm và triển khai IEnumerable có thể được khởi tạo theo cách này. Trình biên dịch chỉ biên dịch mã của bạn như thể bạn đã sử dụng phương thức Thêm này.

hãy xem here

+2

Không hoàn toàn - nó phải triển khai IEnumerable (và phương thức Thêm phải có tham số và phải có một hàm tạo có thể truy cập). –

+0

chỉ cần chỉnh sửa nó :) quên viết nó ở nơi đầu tiên :) –

2

new List{ 1, 2, 3, 4, 5 } chỉ là cú pháp 'đường'. Dưới nắp nó sẽ chỉ đơn giản gọi phương thức Add cho mỗi mục.

+2

Xin downvoter xin vui lòng để lại một bình luận. Cảm ơn. –

+0

hmmm, không ai sở hữu tối đa downvoting câu trả lời đúng. Dân chủ tại nơi làm việc! –

6

Nhìn vào phương pháp này.

public void CreateList() 
    { 
     List<int> list = new List<int> { 1, 2, 3, 4, 5 }; 
    } 

Sau khi biên dịch này, MSIL trông như thế này ..

.method public hidebysig instance void CreateList() cil managed 
{ 
    // Code size  50 (0x32) 
    .maxstack 2 
    .locals init ([0] class [mscorlib]System.Collections.Generic.List`1<int32> list, 
      [1] class [mscorlib]System.Collections.Generic.List`1<int32> '<>g__initLocal0') 
    IL_0000: nop 
    IL_0001: newobj  instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor() 
    IL_0006: stloc.1 
    IL_0007: ldloc.1 
    IL_0008: ldc.i4.1 
    IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0) 
    IL_000e: nop 
    IL_000f: ldloc.1 
    IL_0010: ldc.i4.2 
    IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0) 
    IL_0016: nop 
    IL_0017: ldloc.1 
    IL_0018: ldc.i4.3 
    IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0) 
    IL_001e: nop 
    IL_001f: ldloc.1 
    IL_0020: ldc.i4.4 
    IL_0021: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0) 
    IL_0026: nop 
    IL_0027: ldloc.1 
    IL_0028: ldc.i4.5 
    IL_0029: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0) 
    IL_002e: nop 
    IL_002f: ldloc.1 
    IL_0030: stloc.0 
    IL_0031: ret 
} // end of method Program::CreateList 

Như bạn có thể quan sát, Nó chỉ là một đường cú pháp và trình biên dịch thay thế intialization bởi các cuộc gọi liên tiếp của chương trình Add().

8

Đây là bộ khởi tạo bộ sưu tập, C# 3.0 language feature. Nó đòi hỏi:

  • loại phải thực hiện IEnumerable (mặc dù điều này không bao giờ được sử dụng để khởi tạo)
  • kiểu kết nối phải có ít nhất một Add phương pháp

Nó chỉ đơn giản gọi phương thức Add cho mỗi học kỳ . Bạn cũng có thể sử dụng bộ dữ liệu nếu số Add chấp nhận nhiều giá trị, ví dụ như từ điển. Mỗi học kỳ là sau đó {key,value}:

new Dictionary<int,string> {{1,"abc"},{2,"def"}}; 

Đối với một ví dụ của việc sử dụng này cho những kiểu bespoke:

class Program 
{ 
    static void Main() 
    { 
     new Foo { 1, "abc", { 2, "def" } }; 
    } 
} 

class Foo : IEnumerable 
{ 
    public void Add(int a) { } 
    public void Add(string b) { } 
    public void Add(int a, string b) { } 
    // must implement this!! (but never called) 
    IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); } 
} 
0

Như new List<int>{1,2,3,4,5} là mảng khởi, tôi thích nghĩ rằng nó hoạt động này ra trong nội bộ bởi ma thuật kể từ khi tôi không thể ảnh hưởng đến cách nó xảy ra. Nghĩ về nó, nó có thể định nghĩa phương thức mặc định để thêm các phần tử vào bộ sưu tập trong siêu dữ liệu trong đó [] được thực hiện theo chỉ mục và những phần thực hiện IList được thực hiện theo phương thức Add.

+0

Tại không phải là "khởi tạo mảng" - đó là một chủ đề riêng biệt hoạt động rất khác nhau. Và vì nó * xảy ra * nó không dựa vào 'IList.Add' hoặc (nhưng đó là một giả định hợp lý). –

+0

Tôi muốn nói rằng việc khởi tạo bộ sưu tập cũng có thể hữu ích cho OP http://stackoverflow.com/questions/459652/why-do-c-collection-initializers-work-this-way – Bablo

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