Параметры Тип IEnumerable с#


Почему я не могу использовать IEnumerable с парами? Это когда-нибудь будет исправлено? Я действительно хочу, чтобы они переписали старые библиотеки, чтобы использовать дженерики...

3 52

3 ответа:

Почему я не могу использовать IEnumerable с params?

вопрос предполагает, что проектная группа должна предоставить причину не добавить функцию языка. Это предположение ложно.

скорее, для того, чтобы функция была использована вами, она должна быть продумана, разработана, определена, реализована, протестирована, документирована и отправлена. Все это большие затраты.

функция "params enumerable" была придумано и спроектировано. Он никогда не был определен, реализован, протестирован, задокументирован или отгружен.

поэтому вы не можете использовать эту функцию.


UPDATE: на момент написания этой статьи-начало 2015 года-теперь было указано, но реализация, тестирование, документация и доставка были сокращены для C# 6.0 во второй части 2014 года. Смотрите объявление Люциана здесь:http://roslyn.codeplex.com/discussions/568820.

так как он до сих пор не был реализовано, протестировано, документировано и отправлено, до сих пор нет такой функции. Надеюсь, это превратит его в гипотетическую будущую версию C#.


UPDATE: я должен уточнить, что я имею в виду под "функцией", поскольку возможно, у всех нас есть разные идеи в наших головах, что такое "функция". Я говорю о том, чтобы позволить вам сказать что-то вроде

void Frob(params IEnumerable<int> x)
{
    foreach(int y in x) ...
}

и тогда сайт вызова может быть либо в "нормальной форме" передачи последовательности целые числа, или" расширенная форма " Frob(10, 20, 30). Если в развернутой форме компилятор генерирует вызов, как если бы вы сказали Frob(new int[] { 10, 20, 30}), то же самое, что и для массивов param. Дело в том, что часто бывает так, что метод никогда не использует произвольный доступ к массиву, и поэтому мы могли бы ослабить требование, чтобы параметры были массивом. Вместо этого парамы могут быть просто последовательностью.

вы можете сделать это сегодня сделать перегрузка:

void Frob(params int[] x) { Frob((IEnumerable<int>)x); }

void Frob(IEnumerable<int> x)
{
    foreach(int y in x) ...
}

что немного больно. Мы могли бы просто позволить вам использовать IEnumerable в качестве типа аргумента params и покончим с этим.

это когда-нибудь будет исправлено?

Я надеюсь на это. Эта функция была в списке в течение длительного времени. Это сделало бы много функций работать гораздо лучше с LINQ.

Frob(from c in customers select c.Age);

без необходимости писать две разные версии Frob.

однако, это просто функция "небольшое удобство"; на самом деле это не добавляет много новой силы к языку. Вот почему его никогда не было достаточно высоко в списке приоритетов, чтобы сделать его на этапе "спецификация написана".

Я действительно хочу, чтобы они переписали старые библиотеки, чтобы использовать дженерики.

комментарии отметил.

Я мая теперь понял, что вы имеете в виду. Я думаю, что вы хотите иметь возможность объявить такой метод:

public void Foo<T>(params IEnumerable<T> items)
{
}

и затем можно вызвать его с" нормальным " аргументом следующим образом:

IEnumerable<string> existingEnumerable = ...;
Foo(existingEnumerable);

или с несколькими параметрами вроде этого:

Foo("first", "second", "third");

это то, что вам нужно? (Заметим, что вы хотите, чтобы первая форма использовала T=string, а не T=IEnumerable<string> С одним элементом...)

если да, то я согласен может быть полезным - но это достаточно просто:

public void Foo<T>(params T[] items)
{
    Foo((IEnumerable<T>) items);
}

public void Foo<T>(IEnumerable<T> items)
{
}

Я не считаю, что делаю это достаточно часто, чтобы сделать выше особенно уродливый обходной путь.

обратите внимание, что при вызове вышеуказанного кода вы захотите явно укажите аргумент типа, чтобы компилятор не предпочитал params пример. Так например:

List<string> x = new List<string>();
Foo<string>(x);

параметры params отправляются в виде массива и IEnumerable<T> не обеспечивает произвольный доступ, необходимый для работы в качестве массива.

вы должны создать массив из IEnumerable при вызове метода:

TheMethod(theIEnumerable.ToArray());