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团队并不把它们视为高优先级项目。