С# использовать System.Type как общий параметр

У меня есть список типов (System.Type), которые необходимо запросить в базе данных.

Для каждого из этих типов мне нужно вызвать следующий метод расширения (который является частью LinqToNhibernate):

Session.Linq<MyType>()

Однако у меня нет MyType, но я хочу использовать Type вместо.

У меня есть:

System.Type typeOne;

Но я не могу выполнить следующее:

Session.Linq<typeOne>()

Как я могу использовать параметр "Тип как общий"?

Ответ 1

Вы не можете, прямо. Точка дженериков заключается в обеспечении безопасности типа компиляции, когда вы знаете тип, который вам интересен во время компиляции, и можете работать с экземплярами этого типа. В вашем случае вы знаете только Type, поэтому вы не можете получать какие-либо проверки времени компиляции, которые имеют любые объекты, которые у вас есть, экземпляры этого типа.

Вам нужно будет вызвать метод через отражение - что-то вроде этого:

// Get the generic type definition
MethodInfo method = typeof(Session).GetMethod("Linq", 
                                BindingFlags.Public | BindingFlags.Static);

// Build a method with the specific type argument you're interested in
method = method.MakeGenericMethod(typeOne);
// The "null" is because it a static method
method.Invoke(null, arguments);

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

Ответ 2

Для этого вам нужно использовать отражение:

typeof(Session).GetMethod("Linq").MakeGenericMethod(typeOne).Invoke(null, null);

(предполагая, что Linq<T>() является статическим методом для типа Session)

Если Session - фактически объект, вам нужно знать, где фактически объявлен метод Linq, и передать в Session в качестве аргумента:

typeof(DeclaringType).GetMethod("Linq").MakeGenericMethod(typeOne)
     .Invoke(null, new object[] {Session});