C# 如果*没有MethodInfo,如何使用MSIL*在实例上调用方法?

C# 如果*没有MethodInfo,如何使用MSIL*在实例上调用方法?,c#,reflection,dynamic-programming,cil,C#,Reflection,Dynamic Programming,Cil,我有一个遵循特定约定的类的一些属性。例如 Person1 { get; set; } Person2 { get; set; } Person3 { get; set; } 我不想在类的实例上获取MethodInfo对象,而是执行如下操作: ... il.Emit(OpCodes.Callvirt, [instance]["set_Person" + index]); 上面的代码行是说明性的,而不是我认为应该是的 有人知道我该怎么做吗?公共类示例 public class Sample {

我有一个遵循特定约定的类的一些属性。例如

Person1 { get; set; }
Person2 { get; set; }
Person3 { get; set; }
我不想在类的实例上获取
MethodInfo
对象,而是执行如下操作:

...
il.Emit(OpCodes.Callvirt, [instance]["set_Person" + index]);
上面的代码行是说明性的,而不是我认为应该是的

有人知道我该怎么做吗?

公共类示例
public class Sample
{
    public int Person1 { get; set; }
    public int Person2 { get; set; }
    public int Person3 { get; set; }
}

static void Main(string[] args) {
    var s = new  Sample();
    var tuples = new List<Tuple<string, int>> { 
                    Tuple.Create("Person1", 1), 
                    Tuple.Create("Person2", 2), 
                    Tuple.Create("Person3", 3) 
                 };

    var argument = Expression.Constant(s);

    foreach (var item in tuples) {
        CreateLambda(item.Item1, argument, item.Item2)
               .Compile()
               .DynamicInvoke();
    }
 }

static LambdaExpression CreateLambda(string propertyName, Expression instance, int value) {
     return Expression.Lambda(
               Expression.Assign(
                  Expression.PropertyOrField(instance, propertyName), 
                  Expression.Constant(value)));
 }
{ 公共int Person1{get;set;} 公共int Person2{get;set;} 公共int Person3{get;set;} } 静态void Main(字符串[]参数){ var s=新样本(); 变量元组=新列表{ Tuple.Create(“Person1”,1), Tuple.Create(“Person2”,2), Tuple.Create(“Person3”,3) }; 变量参数=表达式常数; foreach(元组中的变量项){ CreateLambda(item.Item1,参数,item.Item2) .Compile() .DynamicInvoke(); } } 静态LambdaExpression CreateLambda(字符串属性名称、表达式实例、int值){ 返回表达式.Lambda( 表达式.赋值( Expression.PropertyOrField(实例,propertyName), 表达式。常量(值)); }
这是不可能做到的,我不理解这一点或任何潜在的好处。MSIL Callvirt指令不采用描述调用内容的字符串,而是采用指向特定类型上特定方法的元数据标记,通过反射获取该值的唯一方法是使用MethodInfo实例

这看起来并不是一个复杂的选择:

il.Emit(OpCodes.Callvirt, type.GetMethod("set_Person" + index));

使用DynamicMethod类。在MSDN库的文章中有关于如何使用它的很好的文档。索引来自哪里?是您正在创建的方法的参数吗?或者在这个方法中它应该是常量?@svick:“索引”来自DynamicMethod的创建者中的for循环。那么为什么不想获取
MethodInfo
?这不会对生成代码的性能产生任何影响。不,不会。在本例中,运行时没有
MethodInfo
。这看起来不错,但并不完全是我想要的。:)让我试试看。我问这个问题的原因是出于性能原因。如果我不必使用1000次反射,我相信我会获得一些速度。谢谢你的评论。1000次对用户来说是完全不可见的。如果您发出IL,那么您应该缓存生成的方法或类并重用它们,而不是每次调用方法时都发出IL,因此性能优势为零。此外,如果您正在发送IL,您通常会调用静态链接代码中不存在的方法,即动态发现的方法或其他IL发送的方法,您可以将这些方法作为MethodInfo对象传入。也就是说,如果您搜索它,会有很多对
typeof(SomeClass)的类似构造的请求
例如:
methodof(SomeClass.SomeMethod)
fieldof(SomeClass.someField)
propertyof(SomeClass.SomeProperty)
,但我不会让你屏住呼吸,CLR团队并不把它们视为高优先级项目。