2011-09-20 3 views
0

Вот мой сценарий,Почему параметры не принимают общие типы?

Функция:

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"

Но его показ ошибка, если я вызываю функцию без типа convrsion, как

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

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

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

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

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

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

ответ

4

Обратный тип 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.

+0

Спасибо .... не могли бы вы отправить сообщение, почему вы предложили 'Foreach' вместо' for'loop. 'Foreach' - тип объекта .... так что это будет больше времени по сравнению с типом индекса (' for') ??? –

+1

@Pramodh: 'foreach' - абстракция более высокого уровня - код чище и выражает то, что вы пытаетесь достичь более близко. Фактически, цикл 'foreach' над массивом будет использовать указатель массива в любом случае, но вы обычно не должны даже заботиться о производительности на этом уровне детализации, пока не обнаружите, что есть проблема. Производительность вашего кода * ужасная * для больших массивов, из-за использования конкатенации строк - любая разница между 'foreach' и' for' будет * ничего * по сравнению с этой неэффективностью. –

4

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

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

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

public String StringConcat(IEnumerable<string> parameter) 
{ 
    // your code here 
} 
1

Это ограничение Params по конструкции, так как если бы вы использовали

public String StringConcat(params object[] parameter) 

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

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

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

Смежные вопросы