如何获取方法中引用的所有属性?
How to get all properties referenced in a method?
假设我们有一些 class 人最终消费:
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()
我尝试在 GetMethodReferences
中包含 OpCodes.Callvirt
,但虚拟 get
方法似乎具有的唯一属性是 CompilerGeneratedAttribute
(没有过时的属性)。
接下来我决定深入了解虚拟 get
方法。迭代虚拟方法的指令,注意有一个 ldfld
(load field) 指令:
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
// ...
我认为我实际需要做的是为 SampleProperty
获取 PropertyDefinition
或 PropertyReference
,但我似乎无法弄清楚如何在消费者方法的上下文。
想法?
在 IL 中,方法没有 属性 的概念,只有 属性 的方法概念。我认为塞西尔反映了这一点,所以你不能从 MethodDefinition
到 PropertyDefinition
,但你可以反过来做。
代码可能类似于(未经测试):
MethodDefinition method;
PropertyDefinition property = method.DeclaringType.Properties
.SingleOrDefault(p => p.GetMethod == method || p.SetMethod == method);
请记住,理论上单个方法可能属于多个属性,但我认为任何理智的编译器都不会这样做。
假设我们有一些 class 人最终消费:
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()
我尝试在 GetMethodReferences
中包含 OpCodes.Callvirt
,但虚拟 get
方法似乎具有的唯一属性是 CompilerGeneratedAttribute
(没有过时的属性)。
接下来我决定深入了解虚拟 get
方法。迭代虚拟方法的指令,注意有一个 ldfld
(load field) 指令:
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
// ...
我认为我实际需要做的是为 SampleProperty
获取 PropertyDefinition
或 PropertyReference
,但我似乎无法弄清楚如何在消费者方法的上下文。
想法?
在 IL 中,方法没有 属性 的概念,只有 属性 的方法概念。我认为塞西尔反映了这一点,所以你不能从 MethodDefinition
到 PropertyDefinition
,但你可以反过来做。
代码可能类似于(未经测试):
MethodDefinition method;
PropertyDefinition property = method.DeclaringType.Properties
.SingleOrDefault(p => p.GetMethod == method || p.SetMethod == method);
请记住,理论上单个方法可能属于多个属性,但我认为任何理智的编译器都不会这样做。