假设我们有一些人最终会消费:
public class SampleClass
{
[Obsolete("This property was slain in Moria", false)]
public double SampleProperty { get; set; }
[Obsolete("This method was slain in Moria", false)]
public static void SampleMethod()
{
}
}
然后让我们说有人消费它:
public static double SampleConsumer()
{
SampleClass.SampleMethod();
var classy = new SampleClass();
return classy.SampleProperty;
}
我正在尝试确定SampleConsumer
中对过时方法和属性的所有引用。
我已经想出了如何获取这些方法,感谢Kris's response to this question.总之,这看起来像:
public static void GetMethodReferences(MethodDefinition method)
{
foreach (var instruction in method.Body.Instructions)
{
if (instruction.OpCode == OpCodes.Call)
{
MethodReference methodCall = instruction.Operand as MethodReference;
// ...
其中methodCall.CustomAttributes
将包含我们希望检测的过时属性。
我正在尝试为属性引用完成类似的事情。
到目前为止我尝试过:
请注意,在CIL中,classy.SampleProperty
由callvirt
指令表示:
System.Double FoobarNamespace.SampleClass::get_SampleProperty()
我尝试在OpCodes.Callvirt
中包含GetMethodReferences
,但虚拟get
方法似乎唯一的属性是CompilerGeneratedAttribute
(没有过时的属性)。
接下来,我决定查看虚拟get
方法。迭代虚拟方法的说明,请注意有ldfld
( l oa d f ,即 ld )说明:
System.Double FoobarNamespace.SampleClass::<SampleProperty>k__BackingField
我尝试检查它是否有过时的属性:
// for each instruction in the virtual get_SampeProperty()
if (instruction.OpCode == OpCodes.Ldfld)
{
var fieldDefinition = instruction.Operand as MethodDefinition;
// check fieldDefinition.Attributes
// check fieldDefinition.CustomAttributes
// but neither of them have the Obsolete attribute
// ...
我认为我实际需要做的是为PropertyDefinition
获取PropertyReference
或SampleProperty
,但我似乎无法弄清楚如何在{消费者方法。
想法?
答案 0 :(得分:0)
在IL中,没有方法的属性概念,只有属性的方法概念。我认为塞西尔反映了这一点,所以你不能从MethodDefinition
到PropertyDefinition
,但你可以反过来做。
代码看起来像(未经测试):
MethodDefinition method;
PropertyDefinition property = method.DeclaringType.Properties
.SingleOrDefault(p => p.GetMethod == method || p.SetMethod == method);
请记住,理论上单个方法可能属于多个属性,但我认为任何理智的编译器都不会这样做。