C# use System.Type as Generic parameter
I have a list of types (System.Type) which need te be queried on the database.
For each of this types, I need to call th开发者_运维技巧e following extensionmethod (which is part of LinqToNhibernate):
Session.Linq<MyType>()
However I do not have MyType, but I want to use a Type instead.
What I have is:
System.Type typeOne;
But I cannot perform the following:
Session.Linq<typeOne>()
How can I use a Type as a Generic parameter?
You can't, directly. The point of generics is to provide compile-time type safety, where you know the type you're interested in at compile-time, and can work with instances of that type. In your case, you only know the Type
so you can't get any compile-time checks that any objects you have are instances of that type.
You'll need to call the method via reflection - something like this:
// 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's a static method
method.Invoke(null, arguments);
If you need to use this type a lot, you might find it more convenient to write your own generic method which calls whatever other generic methods it needs, and then call your method with reflection.
To do this you need to use reflection:
typeof(Session).GetMethod("Linq").MakeGenericMethod(typeOne).Invoke(null, null);
(assuming that Linq<T>()
is a static method on the type Session
)
If Session
is actually an object, you'll need to know where the Linq
method is actually declared, and pass in Session
as an argument:
typeof(DeclaringType).GetMethod("Linq").MakeGenericMethod(typeOne)
.Invoke(null, new object[] {Session});
I have one general method which call Call Generic Method Through Reflection
/// <summary>
/// This method call your method through Reflection
/// so i wil call the method like CallGenericMethodThroughReflection<Session>(assemblyQualifiedName,Linq,false,new[] { file })
/// </summary>
/// <typeparam name="T">Call method from which file</typeparam>
/// <param name="assemblyQualifiedName">Your can get assemblyQualifiedName like typeof(Payroll.Domain.Attendance.AttendanceApplicationMaster).AssemblyQualifiedName</param>
/// <param name="methodName"></param>
/// <param name="isStaticMethod"></param>
/// <param name="paramaterList"></param>
/// <param name="parameterType">pass parameter type list in case of the given method have overload </param>
/// <returns>return object of calling method</returns>
public static object CallGenericMethodThroughReflection<T>(string assemblyQualifiedName, string methodName,bool isStaticMethod ,object[] paramaterList,Type[] parameterType = null)
{
try
{
object instance = null;
var bindingAttr = BindingFlags.Static | BindingFlags.Public;
if (!isStaticMethod)
{
instance = Activator.CreateInstance<T>();
bindingAttr = BindingFlags.Instance | BindingFlags.Public;
}
MethodInfo MI = null;
var type = Type.GetType(assemblyQualifiedName);
if(parameterType == null)
MI = typeof(T).GetMethod(methodName, bindingAttr);
else
MI = typeof(T).GetMethod(methodName, bindingAttr,null, parameterType, null);//this will work in most case some case not work
if (type == null || MI == null) // if the condition is true it means given method or AssemblyQualifiedName entity not found
return null;
var genericMethod = MI.MakeGenericMethod(new[] { type });
return genericMethod.Invoke(instance, paramaterList);
}
catch (Exception ex)
{
throw ex;
}
}
精彩评论