Почему params не принимает универсальные типы? - PullRequest
0 голосов
/ 20 сентября 2011

Вот мой сценарий,

Функция:

    public String StringConcat(params String[] parameter)
    {
        String l_strReturnValue = String.Empty;
        for (Int32 l_nIndex = 0; l_nIndex < parameter.Length; l_nIndex++)
        {
            l_strReturnValue += parameter[l_nIndex];
        }
        return l_strReturnValue;
    }

И я называю это как

        List<String> l_lstTest = new List<string> { "A", "B", "C" };
        String l_strString = StringConcat(l_lstTest.Select(X => X).ToArray());

, она возвращает значение как "ABC"

Но отображается ошибка, если я вызываю функцию без определения типа, например

        String l_strString = StringConcat(l_lstTest.Select(X => X));

Так как использовать функцию без преобразования?

Примечание 1:

В методе XDocument Add - они использовали как params, но нет необходимости в преобразованиях типов.

Примечание 2:

Цель этого поста - не добавлять строки, а просто узнать больше об ограничениях params.

Ответы [ 3 ]

4 голосов
/ 20 сентября 2011

Ограничение для ключевого слова params состоит в том, что параметр должен иметь тип массива.

l_lstTest.Select(X => X) - это IEnumerable<string>, а не массив, поэтому он не соответствует формальному типу параметра. Это не работает по той же причине, что не будет работать, если вы попытаетесь передать простой int.

Чтобы это сработало, вы должны добавить еще одну перегрузку метода:

public String StringConcat(IEnumerable<string> parameter)
{
    // your code here
}
4 голосов
/ 20 сентября 2011

Тип возврата Select(X => X) будет IEnumerable<string> - не массив.Так что вам нужна еще одна перегрузка:

public String StringConcat(IEnumerable<string> parameter)

Вы, вероятно, заставите перегрузку массива вызывать эту перегрузку.

(И да, очевидно, что вы захотите использовать StringBuilder вместо повторенияконкатенация строк - и foreach вместо цикла for.

Обратите внимание, что соответствующая перегрузка XDocument.Add принимает параметр params Object[], а не params String[] - и LINQ to XML работает так, что есливы пытаетесь добавить что-то, что само по себе перечислимо, как если бы вы добавляли каждый элемент по очереди.Это не часть языка - это часть реализации.Поэтому, если вы позвоните:

doc.Add(someStringArray.Select(x => x))

, то на самом деле просто вызовете XDocument.Add(object), который заметит , что аргумент реализует IEnumerable.

1 голос
/ 20 сентября 2011

Это ограничение параметров по дизайну, потому что, если вы использовали

  public String StringConcat(params object[] parameter)

и вы вызывали с IEnumerable, вы не могли понять, является ли параметр одним параметром или он должен повторяться для перечислимого. Например, без этого ограничения в

  StringConcat( l_lstTest.Select(X => X) )

IEnumerable должен быть элементом списка параметров или это список параметров?

...