如何知道给定对象是否包含任何动态属性

本文关键字:动态 属性 何动态 包含任 何知道 对象 是否 | 更新日期: 2023-09-27 18:29:14

我正在使用第三方api开发应用程序。他们提供了一个示例应用程序来演示API。在示例应用程序中,有一个属性网格,显示所选对象的所有属性。在示例应用程序中,我可以看到一个属性,比如"X",但从程序上讲,我无法通过在对象变量后面放点(.)来访问它。我也使用了反射来获得属性,但没有成功。有人认为这可能是一个动态属性。我找不到任何方法来检查给定的对象或该对象的任何成员是否是动态的?

请建议访问该房产的方法。

PropertGrid控件能够显示上述属性,也允许更改值,但该属性无法按语法访问。

如何知道给定对象是否包含任何动态属性

解决此问题的方法是直接查看生成的具有动态属性的类型的IL。在那里,您会发现这样的属性只表示为对象类型,而且它的所有组件都使用DynamicAttribute属性进行装饰。

此属性由编译器本身放置,开发人员不能使用。因此,您只需要检查属性是否使用DynamicAttribute属性进行了装饰。

要了解这一点,请查看IamDynamic属性的Get访问器方法的以下IL代码,我们稍后将使用该方法进行测试。

.method public hidebysig specialname instance object 
      get_IamDynamic() cil managed
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 
.param [0]
.custom instance void [System.Core]System.Runtime.CompilerServices.DynamicAttribute::.ctor() = ( 01 00 00 00 ) 
.maxstack  1
.locals init (object V_0)
IL_0000:  ldarg.0
IL_0001:  ldfld      object Testing.TestClass::'<IamDynamic>k__BackingField'
IL_0006:  stloc.0
IL_0007:  br.s       IL_0009
IL_0009:  ldloc.0
IL_000a:  ret

您可以很容易地注意到使用DynamicAttribute的行,这表明这是一个动态声明。现在,我们可以使用以下扩展方法来发现所有的动态属性。

public static class DynamicExtension
{
    public static void GetDynamicProperties(this Type source)
    {
        source.GetProperties()
              .Where(x => x.GetCustomAttributes().OfType<DynamicAttribute>().Any())
              .ToList()
              .ForEach(x => Console.WriteLine(x.Name));
    }
}

上面提到的这个类将进行动态特性测试。

class TestClass
{
    public dynamic IamDynamic { get; set; }        
    public object IamNotDynamic { get; set; }
    public dynamic IamAlsoDynamic { get; set; }
}

执行以下代码行后,您将看到仅显示两个动态属性。

class Program
{
    static void Main()
    {
        typeof(TestClass).GetDynamicProperties();
        Console.Read();
    }
}