Каков самый простой и компактный способ создания IEnumerable или ICollection?
итак, много раз у нас есть функция, которая принимает IEnumerable или ICollection в качестве параметра. В случаях, когда у нас есть отдельные элементы, но нет коллекции для их хранения, мы должны создать коллекцию перед передачей их функции, например:
T o1, o2, o3;
Foo(new T[] { o1, o2, o3 });
Я всегда создавал массив или список, как в последнем примере. Но интересно, есть ли более элегантный способ создать необходимый IEnumerable или ICollection?
было бы совсем круто, если бы можно было сделать это:
Foo({ o1, o2, o3 });
и компилятор создаст наиболее абстрактную возможную коллекцию, которая удовлетворит потребности IEnumerable или ICollection (в зависимости от того, какую функцию принимает).
во всяком случае, как вы передадите O1, o2 и o3 к IEnumerable или параметрам ICollection?
5 ответов
текущая версия C# (3) поддерживает нотацию без явного типа, т. е.
Foo(new [] { o1, o2, o3 })
создать массив. Там же LINQ в это Enumerable.Range
для создания непрерывного диапазона чисел. Все остальное должно быть реализовано. В духе Java:
public static IEnumerable<T> AsList<T>(params T[] values) {
return values;
}
называться так:
Foo(Enumerable.AsList(o1, o2, o3));
иногда я использовал метод с аргументом "params".
Foo(params T[] ts)
и если я настроен на IEnumerable, у меня просто есть этот делегат метода тому, кто хочет IEnumerable.
Foo(params T[] ts) { Foo(ts.AsEnumerable()); }
вы должны вызвать AsEnumerable или вы собираетесь рекурсировать.
предполагая, что Foo ожидает IEnumerable
T o1, o2, o3;
Foo(new []{o1, o2, o3});
Создание массива и передача, вероятно, самый простой / самый элегантный способ выполнить это в текущей версии C#. Вы можете воспользоваться преимуществами неявного ввода массива (т. е. new[] { ... }
, но это все, что он идет.
Я подозреваю, что вы действительно ищете эквивалент C# этого синтаксиса F#:
let foo = seq [ o1; o2; o3 ]
, который генерирует IEnumerable<T>
это будет повторяться над указанными элементами. ("Seq" на самом деле является псевдонимом F# для "IEnumerable", хотя F# имеет встроенный их поддержка.)
к сожалению, поскольку это в значительной степени функциональное понятие, нет эквивалента C#, хотя кто знает, когда он будет добавлен, поскольку C# становится все более и более функциональным.
если у вас есть метод, который принимает массив в качестве последнего параметра, может иметь смысл отметить этот параметр params
. Это позволяет вызвать метод следующим образом:
Foo(o1, o2, o3);
Я нахожу это особенно полезно при написании модульных тестов для Foo()
, потому что часто в тесте на мои параметры отдельно, а не в массиве.
я советую не делать этого, если есть перегрузка Foo()
это не принимает массив в этой позиции, потому что он может быстро сбивает с толку.
Я хочу, чтобы язык C# разрешил params
на IList<T>
:
void Foo(params IList<T> ts) { ... }