如何在不进行字符串比较的情况下获取class函数的MethodInfo
How to get the MethodInfo of a function of a class, without string comparison
类似于我之前的一个问题,当我询问获取字段的 FieldInfo 时,,根据那里的答案,我编译了这个助手 class,
using System;
using System.Reflection;
using System.Linq.Expressions;
internal class Program
{
class MyClass
{
#pragma warning disable 0414, 0612, 0618, 0649
private int myInt = 24;
#pragma warning restore 0414, 0612, 0618, 0649
public const BindingFlags _flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
public MyClass()
{
MemberInfo myIntMI = GetMemberInfo(this, c => c.myInt);
Console.WriteLine(myIntMI.Name + ": " + GetFieldValue(myIntMI) + ", " + GetFieldInfo(myIntMI).FieldType);
// MemberInfo tfMI = GetMemberInfo(this, cw => cw.testFunction());
// MemberInfo tfMI = GetMemberInfo(this, cw => cw.testFunction);
// Console.WriteLine(tfMI.Name + ": " + GetFieldValue(tfMI) + ", " + GetFieldInfo(tfMI).FieldType);
foreach( var mi in GetType().GetMethods(_flags) )
{
Console.WriteLine("method: " + mi);
}
}
private void testFunction() { }
private object GetFieldValue(MemberInfo mi)
{
return GetFieldInfo(mi).GetValue(this);
}
private FieldInfo GetFieldInfo(MemberInfo mi)
{
return GetType().GetField(mi.Name, _flags);
}
private MemberInfo GetMemberInfo<TModel, TItem>(TModel model, Expression<Func<TModel, TItem>> expr)
{
return ( (MemberExpression)expr.Body ).Member;
}
}
}
使用 GetMemberInfo(this, c => c.myInt
效果非常好,但注释掉的行是我现在感到困惑的地方,GetMemberInfo(this, c => c.testFunction)
或 GetMemberInfo(this, c => c.testFunction())
。
有什么方法可以在不进行字符串比较的情况下从 GetMethods()
runthrough 或 GetMethod("testFunction")
?
中获取可用的成员信息
MemberExpression
仅适用于属性和字段。你可能看看 MethodCallExpression
.
所以像
((MethodCallExpression)expr.Body).Method
假设您传递的 lambda 看起来像 () => this.testFunction()
因此,要获得 MemberInfo
,您将获得 Method
属性 的 MemberCallExpression
。
此外,您应该更改 GetMemberInfo
方法签名,因为这是一个不带参数的 lambda,并且 returns 与您的方法 returns 的类型相同,因此它将是 private MemberInfo GetMemberInfo<T>(Expression<Func<T, void>> expr)
或接近它的东西。
我不是 100% 确定,但实际情况是,this.testFunction
实际上是创建委托的语法糖,所以它实际上类似于 new Action(this.testFunction)
假设 testFunction
是 void testFunction()
。或者类似这样的东西,因为 this.testFunction
不是成员访问,而是委托创建。
类似于我之前的一个问题,当我询问获取字段的 FieldInfo 时,
using System;
using System.Reflection;
using System.Linq.Expressions;
internal class Program
{
class MyClass
{
#pragma warning disable 0414, 0612, 0618, 0649
private int myInt = 24;
#pragma warning restore 0414, 0612, 0618, 0649
public const BindingFlags _flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
public MyClass()
{
MemberInfo myIntMI = GetMemberInfo(this, c => c.myInt);
Console.WriteLine(myIntMI.Name + ": " + GetFieldValue(myIntMI) + ", " + GetFieldInfo(myIntMI).FieldType);
// MemberInfo tfMI = GetMemberInfo(this, cw => cw.testFunction());
// MemberInfo tfMI = GetMemberInfo(this, cw => cw.testFunction);
// Console.WriteLine(tfMI.Name + ": " + GetFieldValue(tfMI) + ", " + GetFieldInfo(tfMI).FieldType);
foreach( var mi in GetType().GetMethods(_flags) )
{
Console.WriteLine("method: " + mi);
}
}
private void testFunction() { }
private object GetFieldValue(MemberInfo mi)
{
return GetFieldInfo(mi).GetValue(this);
}
private FieldInfo GetFieldInfo(MemberInfo mi)
{
return GetType().GetField(mi.Name, _flags);
}
private MemberInfo GetMemberInfo<TModel, TItem>(TModel model, Expression<Func<TModel, TItem>> expr)
{
return ( (MemberExpression)expr.Body ).Member;
}
}
}
使用 GetMemberInfo(this, c => c.myInt
效果非常好,但注释掉的行是我现在感到困惑的地方,GetMemberInfo(this, c => c.testFunction)
或 GetMemberInfo(this, c => c.testFunction())
。
有什么方法可以在不进行字符串比较的情况下从 GetMethods()
runthrough 或 GetMethod("testFunction")
?
MemberExpression
仅适用于属性和字段。你可能看看 MethodCallExpression
.
所以像
((MethodCallExpression)expr.Body).Method
假设您传递的 lambda 看起来像 () => this.testFunction()
因此,要获得 MemberInfo
,您将获得 Method
属性 的 MemberCallExpression
。
此外,您应该更改 GetMemberInfo
方法签名,因为这是一个不带参数的 lambda,并且 returns 与您的方法 returns 的类型相同,因此它将是 private MemberInfo GetMemberInfo<T>(Expression<Func<T, void>> expr)
或接近它的东西。
我不是 100% 确定,但实际情况是,this.testFunction
实际上是创建委托的语法糖,所以它实际上类似于 new Action(this.testFunction)
假设 testFunction
是 void testFunction()
。或者类似这样的东西,因为 this.testFunction
不是成员访问,而是委托创建。