假设我们在一个类中有两个公共方法:
public class SomeClass
{
public bool DoSomething(int param1)
{
return param1 == 30;
}
public bool DoSomethingElse(int param1)
{
param1 *= 2;
return param1 == 30;
}
}
我可以编写以下代码来使用反射来获得这两种方法:
MethodInfo[] methods = typeof(SomeClass).GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.ReturnType == typeof(bool)
&& x.GetParameters().Length == 1
&& x.GetParameters()[0].ParameterType == typeof(int)).ToArray();
假设我只想要DoSomethingElse
,我可以使用methods[1]
。
但是,假设他们在下次编译此类时交换了位置。我最终会DoSomething
代替。
分离这两种方法的唯一方法是,DoSomethingElse
在检查之前将参数乘以2。
我还能用反射做其他检查以确保我总是得到DoSomethingElse
吗?
注意:每次编译时,我正在寻找的方法的名称可能都会更改,因此简单地搜索它们的名称也不起作用。
从技术上讲,您可以分析方法的IL代码;让我们检查一下是否* 2
在第一个10
IL代码内:
https://zh.wikipedia.org/wiki/List_of_CIL_instructions
码:
MethodInfo[] methods = GetType()
.GetMethods(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.ReturnType == typeof(bool)
&& x.GetParameters().Length == 1
&& x.GetParameters()[0].ParameterType == typeof(int))
.Where(m => m
.GetMethodBody()
.GetILAsByteArray()
.Take(10) // take first 10 IL codes
.SkipWhile(b => b != 0x18) // ldc.i4.2 : load 2
.Any(b => b == 0x5A)) // mul : multiply
.ToArray();
我们来看一下:
Console.Write(string.Join(Environment.NewLine, methods.Select(m => m.Name)));
结果:
DoSomethingElse
但是,我强烈建议您使用特定方法Name
或带有属性的标记方法等。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句