В частности, я хочу написать это:
public Func<IList<T>, T> SelectElement = list => list.First();
Но я получаю синтаксическую ошибку в T
. Разве у меня нет общего анонимного метода?
В частности, я хочу написать это:
public Func<IList<T>, T> SelectElement = list => list.First();
Но я получаю синтаксическую ошибку в T
. Разве у меня нет общего анонимного метода?
Нет извини. Для этого потребуются общие поля или общие свойства, которые не являются функциями, поддерживаемыми C#. Лучшее, что вы можете сделать, это создать общий метод, который вводит T:
public Func<IList<T>, T> SelectionMethod<T>() { return list => list.First(); }
И теперь вы можете сказать:
Func<IList<int>, int> selectInts = SelectionMethod<int>();
Конечно можно, но T
надо знать:
class Foo<T>
{
public Func<IList<T>, T> SelectionMethod = list => list.First();
}
В качестве альтернативы вы можете использовать универсальный метод, если вы не хотите делать содержащий его класс универсальным:
public Func<IList<T>, T> SelectionMethod<T>()
{
return list => list.First();
}
Но все же кому-то во время компиляции нужно будет знать это T
.
Foo<T>
узнает об этом. Если вы никогда не знаете этого во время компиляции, то дженерики вам не подходят.
- person Darin Dimitrov; 02.12.2010
T
.
- person cdhowie; 02.12.2010
T
, когда я вызываю этот метод, но я использую его в 2 разных местах ( один раз в List‹char›, один раз в List‹string›), и я хочу использовать один и тот же метод для обоих.
- person mpen; 02.12.2010
SelectionMethod
в виртуальный универсальный метод, чтобы пользователь мог его переопределить. Здесь действительно вопрос метода и поля. Методы могут быть универсальными, поля — нет. Так говорит спецификация. Это так просто. Вы не можете бороться против спецификации или системы типов.
- person Darin Dimitrov; 02.12.2010
public void DoSomething<T>(Func<IList<T>, T> foo) { ... }
. Теперь, когда пользователь вызывает этот метод, он может передать в качестве аргумента любое выражение, которое ему нравится: DoSomething(x => x.First());
и внутри метода вы будете выполнять эту работу. Вы могли бы даже предоставить перегрузку этого метода, которая будет делать .First()
вещи: public void DoSomething<T>() { ... }
и внутри вы создадите анонимный делегат.
- person Darin Dimitrov; 02.12.2010
Вы объявили только возвращаемый тип как общий.
Попробуй это:
public Func<IList<T>, T> SelectionMethod<T>() { return list => list.First(); }
Имя объекта, который вы объявляете, должен включать параметры типа, чтобы он был универсальным. Компилятор поддерживает только универсальные классы и универсальные методы.
Итак, для универсального класса вы должны иметь
class MyGeneric<T> {
// You can use T here now
public T MyField;
}
Или, для методов
public T MyGenericMethod<T>( /* Parameters */ ) { return T; }
Вы можете использовать T в качестве возвращаемого параметра, только если он был объявлен в имени метода первым.
Несмотря на то, что похоже, что возвращаемый тип объявлен перед фактическим методом, компилятор не читает его таким образом.