2013-10-02 2 views
18

Это довольно элементарный вопрос, но я никогда раньше не делился с дженериками, и я оказался в необходимости использовать его. К сожалению, у меня нет времени прямо сейчас, чтобы пройти какие-либо учебники, и ответы, которые я нашел связанным с ними, до сих пор не могут быть названы базовыми, поэтому мы идем:Использование списка <T> в C# (Generics)

Предположим, у меня есть следующее:

List<MyClass1> list1 = getListType1(); 
List<MyClass2> list2 = getListType2(); 

if (someCondition) 
    MyMethod(list1); 
else 
    MyMethod(list2); 

И конечно

void MyMethod(List<T> list){ 
    //Do stuff 
} 

Ну, я думал, что это будет так просто, но, видимо, это не так. VS предупреждает меня, что

Аргументы типа для метода MyMethod (System.Collections.Generic.List) не могут быть выведены из эксплуатации

и если я скомпилировать его в любом случае, я получаю

Тип или пространство имен имя «Т» не может быть найден

ошибку.

В многочисленных ответах, которые я нашел, я читал, что я должен объявить, что такое T, что имеет смысл, но я не мог понять, как это сделать в таком упрощенном сценарии. Конечно, эти ответы породили еще больше вопросов, но сейчас я просто хочу объяснить, что я делаю неправильно (кроме того, не изучая дженерики) и как сделать все правильно.

+1

Для одного убедитесь, что у вас есть using System.Collections.Generic; включен. –

+0

Это не то, как работают дженерики. 'MyMethod (Список )) - недопустимая сигнатура метода (если ваш класс не является общим классом с параметром типа T) –

+0

У' MyClass1' и 'MyClass2' есть некоторый общий базовый тип или интерфейс? Разделяют ли они много общих свойств или методов? –

ответ

28

Вам необходимо объявить T против метода, тогда C# может идентифицировать тип, который принимает метод. Попробуйте это:

void MyMethod<T>(List<T> list){ 
    //Do stuff 
} 

Затем вызовите его, выполнив:

if (someCondition) 
    MyMethod(list1); 
else 
    MyMethod(list2); 

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

void MyMethod<T>(List<T> list) where T : MyClassBase 
+3

C# будет выводить тип на основе аргументов, поэтому явно не нужно указывать - очевидно, если в этом методе нет параметров, вам нужно будет указать общие аргументы, но это хорошо, когда они выводятся! – Charleh

+0

@Charleh Хорошая точка, обновлено. – mattytommo

+0

Все ответы работают, я выбрал этот как принятый для того, чтобы быть наиболее полным (включая комментарий @Charleh и последующее обновление). Спасибо вам всем. – makoshichi

7

Вы должны позволить C# знать, какой тип посылается:

List<MyClass1> list1 = getListType1(); 
List<MyClass2> list2 = getListType2(); 

if (someCondition) 
    MyMethod<MyClass1>(list1); 
else 
    MyMethod<MyClass2>(list2); 

void MyMethod<T>(List<T> list){ 
    //Do stuff 
} 
12

Вам необходимо добавить параметр универсального типа для T к вашей методе:

void MyMethod<T>(List<T> list) { 

компилятор не знает, что T представляет собой, в противном случае.

1

В принципе, в классе C# List <T> класс представляет собой строго типизированный список объектов, к которым можно получить доступ по индексу.

И также поддерживает сохранение значений определенного типа без каста на объект или из него.

Мы можем использовать значение Interger & Строковое значение в списке.

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