IEnumerable <object> a = new IEnumerable <object> (); Чи можу я це зробити?


94

Я хочу створити новий екземпляр об'єкта IEnumerable<object>

Чи можу я це зробити?

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


1
Ні, і це навіть не має сенсу.
CodesInChaos

3
@ WingMan20-10: Ну, це ВСЕ змінює. Ви не можете додати до загального IEnumerable<T>. Ви повинні використовувати щось на зразок List<T>.
jason

1
У цьому випадку вам потрібен конкретний масив List <object> objs = new IEnumerable <object>. Ви не можете додавати елементи до ітератора, оскільки це не колекція ... це ітератор :)
user44298

1
@ivo: Зверніть увагу, що IEnumerable<T>не представляє ітератор - він представляє послідовність, що повторюється . IEnumerator<T>сам представляє ітератор.
Jon Skeet

Відповіді:


117

Наприклад, ви можете створити екземпляр List<object>, який реалізує IEnumerable<object>. Приклад:

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

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

11
Враховуючи, що питання показує використання дженериків, наведений приклад типу, який не реалізує загальний, IEnumerable<T>є поганою ідеєю IMO.
Джон Скіт,

Будь-яка проблема з використанням CallFunction (list.AsEnumerable ()) замість IEnumerable <object> en = list; ...
Джина Марано

Я б використовував масив з літеральним ініціалізатором, якщо це можливо, це найефективніший і найлегший перелічуваний тип, доступний у .NET і не має накладних витрат на List <>. Списки слід використовувати лише в тому випадку, якщо ви дійсно потребуєте або хочете мутувати після ініціалізації. Крім того, краще додати System.Linq і викликати .AsEnumerable () у масиві або списку.
Марк

33

Оскільки ви зараз вказали, що хочете додати до нього, те, що ви хочете, не є простим, IEnumerable<T>але принаймні ICollection<T>. Я рекомендую просто використовувати List<T>такий:

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

Ви можете використовувати myList скрізь, де IEnumerable<object>очікується, оскільки це List<object>реалізується IEnumerable<object>.

(стара відповідь перед роз'ясненнями)

Ви не можете створити екземпляр, IEnumerable<T>оскільки це звичайний інтерфейс (Іноді можна вказати реалізацію за замовчуванням, але це зазвичай використовується лише з COM).

Отже, що ви дійсно хочете, це створити екземпляр класу, який реалізує інтерфейс IEnumerable<T> . Поведінка залежить від того, який клас ви вибрали.

Для порожньої послідовності використовуйте:

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

Для непорожнього переліку можна використовувати деяку колекцію, яка реалізує IEnumerable<T>. Поширені варіанти масив T[], List<T>або якщо ви хочете незмінність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});

Іншим поширеним способом реалізації IEnumerable<T>є функція ітератора, представлена ​​в C # 3:

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

IEnumerable<object> e4=MyIterator();


24

Ні, ви не можете, оскільки IEnumerableце інтерфейс.

Ви повинні мати можливість створити порожній екземпляр більшості неінтерфейсних типів, які реалізують IEnumerable, наприклад: -

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

або

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

@AdamRalph: Я проголосував проти, а потім відволікся, тому не міг негайно залишити коментар. Інтерфейси - це типи, тому ваша відповідь є небезпечною помилкою, оскільки вона поширює типову помилку.
jason


1

Я хотів створити новий перелічуваний об’єкт або список і мати можливість додавати до нього.

Цей коментар все змінює. Ви не можете додати до загального IEnumerable<T>. Якщо ви хочете залишитися з інтерфейсами System.Collections.Generic, вам потрібно використовувати клас, який реалізує ICollection<T>like List<T>.


1

Основна причина полягає в тому, що ми не можемо створити об'єкт інтерфейсу, а IEnumerable - це інтерфейс . Нам потрібно створити об’єкт класу, який реалізує інтерфейс. Це основна причина, через яку ми не можемо безпосередньо створити об’єкт IEnumerable.


0

Жоден IEnumerable не є інтерфейсом, ви не можете створити екземпляр інтерфейсу

Ви можете зробити щось подібне

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

Чи можна створити такий екземпляр COM-інтерфейсу, як @Jon Skeet?
Арсен Мкртчян


1
Я думаю, що можна вказати реалізацію за замовчуванням, яка створюється за допомогою замість інтерфейсу для COM-інтерфейсів.
CodesInChaos

@JonSkeet, чи не точніше стверджувати, що виклик new SomeComInterface()екземплярів, пов'язаних з інтерфейсом, "CoClass", а не створення самого інтерфейсу?
phoog

@phoog: Це було б точно, але важливим і дивним є те, що ти можеш використовувати newінтерфейс у певних ситуаціях.
Джон Скіт,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.