데이터베이스에서 쿼리해야하는 유형 (System.Type) 목록이 있습니다.
이 유형 각각에 대해 다음 확장 메서드 (LinqToNhibernate의 일부)를 호출해야합니다.
Session.Linq<MyType>()
그러나 MyType이 없지만 대신 Type을 사용하고 싶습니다.
내가 가진 것은 :
System.Type typeOne;
그러나 다음을 수행 할 수 없습니다.
Session.Linq<typeOne>()
유형을 일반 매개 변수로 어떻게 사용할 수 있습니까?
답변
직접 할 수는 없습니다. 제네릭의 요점은 컴파일 타임에 관심있는 유형을 알고 해당 유형의 인스턴스로 작업 할 수있는 컴파일 타임 유형 안전성 을 제공 하는 것입니다. 귀하의 경우에는을 알고 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's a static method
method.Invoke(null, arguments);
이 유형을 많이 사용해야하는 경우 필요한 다른 제네릭 메서드를 호출하는 고유 한 제네릭 메서드를 작성한 다음 리플렉션을 사용 하여 메서드 를 호출하는 것이 더 편리 할 수 있습니다 .
답변
이렇게하려면 리플렉션을 사용해야합니다.
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});
답변
반사를 통해 일반 메서드 호출을 호출하는 일반적인 메서드가 하나 있습니다.
/// <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;
}
}