gpt4 book ai didi

c# - 如何使用强类型反射查找泛型类方法的 MethodInfo?

转载 作者:可可西里 更新时间:2023-11-01 09:14:24 27 4
gpt4 key购买 nike

我想从具有仅在运行时已知的类型参数的泛型类中获取方法的 MethodInfo

下面是我如何从非泛型类中获取泛型方法的 MethodInfo:

class MyClass
{
public void MyMethod<T> (T arg)
{
}
}

static MethodInfo Resolve (Type type)
{
Expression<Action<MyClass, object>> lambda = (c, a) => c.MyMethod (a);
MethodCallExpression call = lambda.Body as MethodCallExpression;

return call
.Method // Get MethodInfo for MyClass.MyMethod<object>
.GetGenericMethodDefinition () // Get MethodInfo for MyClass.MyMethod<>
.MakeGenericMethod (type); // Get MethodInfo for MyClass.MyMethod<int>
}

Resolve (typeof (int)).Invoke (new MyClass (), new object[] {3});

现在,如果我想用泛型类尝试类似的东西:

class MyClass<T>
{
public void MyMethod (T arg)
{
}
}

static MethodInfo Resolve (Type type)
{
Expression<Action<MyClass<object>, object>> lambda = (c, a) => c.MyMethod (a);
MethodCallExpression call = lambda.Body as MethodCallExpression;

return call
.Method // Get MethodInfo for MyClass<object>.MyMethod
.SomeMagicMethod (); // FIXME: how can I get a MethodInfo
// for MyClass<T>.MyMethod where typeof (T) == type?
}

Resolve (typeof (string)).Invoke (new MyClass<string> (), new object[] {"Hello, World!"});

这可能吗?

最佳答案

public class MyClass<T>
{
public void MyMethod(T arg, bool flag)
{
Console.WriteLine("type: MyClass<{0}>, arg: {1}, flag:{2}", typeof(T),
arg.ToString(), flag);
}
public void MyMethod(T arg)
{
Console.WriteLine("type: MyClass<{0}>, arg: {1}", typeof(T), arg.ToString());
}
}
public class GenericInvokeTest
{
static MethodInfo Resolve(Type type)
{
var name = ActionName<object>(x => (o) => x.MyMethod(o));
var genericType = typeof(MyClass<>).MakeGenericType(new[] { type });
MethodInfo genericTypeMyMethodInfo = genericType.GetMethod(name); // "MyMethod");
genericTypeMyMethodInfo = genericType.GetMethod(name, new[] { type, typeof(bool) });
return genericTypeMyMethodInfo;
}
public static void Test1()
{
Resolve(typeof(string))
.Invoke(new MyClass<string>(), new object[] { "Hello, World!", true });
// Resolve(typeof(string))
.Invoke(new MyClass<string>(), new object[] { "Hello, World!" });
}
}

要使其成为强类型,您应该简化并使用不同的方法:

1) 使用表达式获取操作/方法的名称...

var name = ActionName<object>(x => (o) => x.MyMethod(o));

2)然后做不可避免的反射部分

var genericType = typeof(MyClass<>).MakeGenericType(new[] { type });
MethodInfo genericTypeMyMethodInfo = genericType.GetMethod(name); // "MyMethod");


ActionName 采取类似的方法,例如 OnPropertyChanged(x => x.Property)

public static string ActionName<T>(Expression<Func<MyClass<T>, Action<T>>> expression)
{
return GetMemberName(expression.Body);
}
public static string GetMemberName(Expression expression)
{
switch (expression.NodeType)
{
case ExpressionType.Lambda:
var lambdaExpression = (LambdaExpression)expression;
return GetMemberName(lambdaExpression.Body);
case ExpressionType.MemberAccess:
var memberExpression = (MemberExpression)expression;
var supername = GetMemberName(memberExpression.Expression);
if (String.IsNullOrEmpty(supername))
return memberExpression.Member.Name;
return String.Concat(supername, '.', memberExpression.Member.Name);
case ExpressionType.Call:
var callExpression = (MethodCallExpression)expression;
return callExpression.Method.Name;
case ExpressionType.Convert:
var unaryExpression = (UnaryExpression)expression;
return GetMemberName(unaryExpression.Operand);
case ExpressionType.Parameter:
return String.Empty;
default:
throw new ArgumentException(
"The expression is not a member access or method call expression");
}
}

关于c# - 如何使用强类型反射查找泛型类方法的 MethodInfo?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15959129/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com