Подтвердить что ты не робот

Можете ли вы использовать методы generics в С#, если тип неизвестен до выполнения?

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

foreach(Type someType in listOfTypes)
{
    SomeMethod<someType>();
}

Было бы очень удобно, если бы это сработало, но это не так. Есть ли другой способ достичь того же, что и выше, и почему С# не разрешает это быть юридическим выражением?

Edit: Похоже, что единственный способ сделать это - это отражение, которое может быть слишком медленным для наших нужд. Любое понимание того, почему нет эффективного способа встраивания, и работает ли что-то подобное в С# 4.0?

4b9b3361

Ответ 1

Вы можете использовать отражение. Предполагая, что текущий объект содержит метод SomeMethod(), код для этого будет выглядеть так:

GetType().GetMethod("SomeMethod").
    MakeGenericMethod(new Type[] { someType }).Invoke(this, null);

Обратите внимание, что если SomeMethod() не является общедоступным, ваш код может не выполняться в средах с более низким доверием.

Ответ 2

Почему С# не разрешает это быть юридическим выражением?

Как отмечали другие, вы не можете этого сделать. Почему нет? Ну, рассмотрим ваш пример:

foreach(Type someType in listOfTypes)
{
    SomeMethod<someType>();
}

Обратите внимание, что каждый тип в списке типов не может быть известен до выполнения, тогда как параметр типа SomeMethod должен быть известен во время компиляции. Компилятор не может сообщить, к какому SomeMethod<T> разрешить ваш вызов, поэтому это незаконно.

В С# 4 это и многие другие подобные вещи будут возможны с включением DLR в CLR. В частности, вызов динамического метода позволит вам вызывать методы, которые могут быть неизвестны во время компиляции.