IEnumerable <object> a = new IEnumerable <object> (); Tôi có thể làm điều này?


90

Tôi muốn tạo một phiên bản mới của một đối tượng IEnumerable<object>

Tôi có thể làm điều này?

IEnumerable<object> a = new IEnumerable<object>();


1
Không, và nó thậm chí không có ý nghĩa.
— CodesInChaos

3
@ WingMan20-10: Chà, điều đó thay đổi MỌI THỨ. Bạn không thể thêm vào chung chung IEnumerable<T>. Bạn phải sử dụng một cái gì đó như thế nào List<T>.
— jason

1
Trong trường hợp này, bạn cần một danh sách mảng cụ thể <object> objs = new IEnumerable <object>. Bạn không thể thêm các mục vào một iterator bởi vì nó không phải là một bộ sưu tập ... một iterator của nó :)
— user44298

1
@ivo: Lưu ý rằng IEnumerable<T>nó không đại diện cho một trình lặp - nó đại diện cho một chuỗi có thể lặp lại . IEnumerator<T>chính nó đại diện cho trình lặp.
— Jon Skeet

Câu trả lời:


114

Ví dụ, bạn có thể tạo một phiên bản của List<object>, thực hiện IEnumerable<object>. Thí dụ:

List<object> list = new List<object>();
list.Add(1);
list.Add(4);
list.Add(5);

IEnumerable<object> en = list;
CallFunction(en);

11
Cho rằng câu hỏi cho thấy việc sử dụng generic, đưa ra một ví dụ về kiểu không triển khai generic IEnumerable<T>là một ý tưởng tồi IMO.
— Jon Skeet

Bất kỳ vấn đề với việc sử dụng CallFunction (list.AsEnumerable ()) thay vì IEnumerable <object> en = danh sách; ...
— Gina Marano

Tôi sẽ sử dụng một mảng với bộ khởi tạo theo nghĩa đen nếu có thể, đó là kiểu liệt kê nhẹ và hiệu quả nhất có sẵn trong .NET và không có chi phí của Danh sách <>. Danh sách chỉ nên được sử dụng nếu bạn thực sự cần hoặc muốn thay đổi sau khi khởi tạo. Ngoài ra, tốt hơn là thêm System.Linq và gọi .AsEnumerable () trên mảng hoặc danh sách.
— Đánh dấu

33

Vì bây giờ bạn đã chỉ định bạn muốn thêm vào nó, những gì bạn muốn không phải là đơn giản IEnumerable<T>nhưng ít nhất là một ICollection<T>. Tôi khuyên bạn nên sử dụng một cách đơn giản List<T>như sau:

List<object> myList=new List<object>();
myList.Add(1);
myList.Add(2);
myList.Add(3);

Bạn có thể sử dụng myList ở mọi nơi IEnumerable<object>mà bạn mong đợi, vì List<object>triển khaiIEnumerable<object> .

(câu trả lời cũ trước khi làm rõ)

Bạn không thể tạo một phiên bản IEnumerable<T>vì đó là một giao diện bình thường (Đôi khi có thể chỉ định một triển khai mặc định, nhưng điều đó thường chỉ được sử dụng với COM).

Vì vậy, những gì bạn thực sự muốn là khởi tạo một lớp thực hiện giao diện IEnumerable<T> . Hành vi khác nhau tùy thuộc vào lớp bạn chọn.

Đối với một trình tự trống, hãy sử dụng:

IEnumerable<object> e0=Enumerable.Empty<object>();

Đối với một liệt kê không trống, bạn có thể sử dụng một số bộ sưu tập có triển khai IEnumerable<T>. Sự lựa chọn phổ biến là mảng T[], List<T>hoặc nếu bạn muốn tính bất biến ReadOnlyCollection<T>.

IEnumerable<object> e1=new object[]{1,2,3};
IEnumerable<object> e2=new List<object>(){1,2,3};
IEnumerable<object> e3=new ReadOnlyCollection(new object[]{1,2,3});

Một cách phổ biến khác để triển khai IEnumerable<T>là tính năng trình lặp được giới thiệu trong C # 3:

IEnumerable<object> MyIterator()
{
  yield return 1;
  yield return 2;
  yield return 3;
}

IEnumerable<object> e4=MyIterator();


24

Không, bạn không thể vì IEnumerablelà một giao diện.

Bạn sẽ có thể tạo một phiên bản trống của hầu hết các kiểu không phải giao diện triển khai IEnumerable, ví dụ: -

IEnumerable<object> a = new object[] { };

hoặc là

IEnumerable<object> a = new List<object>();

@AdamRalph: Tôi đã phản đối và sau đó bị phân tâm, vì vậy không thể để lại nhận xét ngay lập tức. Giao diện là các loại, vì vậy câu trả lời của bạn sai một cách nguy hiểm vì nó truyền bá một quan niệm sai lầm phổ biến.
— jason

7

Không, bạn không thể làm điều đó. Sử dụng dòng mã sau để thay thế:

IEnumerable<int> usersIds = new List<int>() {1, 2, 3}.AsEnumerable();

Tôi hy vọng nó sẽ giúp.


1

Tôi muốn tạo một đối tượng hoặc danh sách có thể liệt kê mới và có thể thêm vào nó.

Nhận xét này thay đổi mọi thứ. Bạn không thể thêm vào chung chung IEnumerable<T>. Nếu bạn muốn ở lại với các giao diện trong System.Collections.Generic, bạn cần sử dụng một lớp thực hiện ICollection<T>như List<T>.


1

Lý do chính là chúng ta không thể tạo đối tượng của một giao diện và IEnumerable là một giao diện . Chúng ta cần tạo đối tượng của lớp thực thi giao diện. Đây là lý do chính mà chúng ta không thể tạo trực tiếp đối tượng của IEnumerable.


0

Không có IEnumerable là một giao diện, bạn không thể tạo phiên bản của giao diện

bạn có thể làm một cái gì đó như thế này

IEnumerable<object> a = new object[0];

Có thể tạo phiên bản của giao diện COM như @Jon Skeet không?
— Arsen Mkrtchyan


1
Tôi nghĩ rằng có thể chỉ định một triển khai mặc định được khởi tạo thay vì giao diện cho các giao diện COM.
— CodesInChaos

@JonSkeet không chính xác hơn khi nói rằng gọi new SomeComInterface()khởi tạo "CoClass" liên quan của giao diện hơn là khởi tạo chính giao diện đó sao?
— phoog

@phoog: Điều đó sẽ chính xác - nhưng điều quan trọng và kỳ lạ là bạn có thể sử dụng newvới một giao diện trong một số tình huống nhất định.
— Jon Skeet

0

Bạn có thể làm được việc này:

IEnumerable<object> list = new List<object>(){1, 4, 5}.AsEnumerable();
CallFunction(list);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.