我正在使用第三方API开发应用程序。他们提供了一个示例应用程序来演示API。在示例应用程序中有一个propertygrid,它显示所选对象的所有属性。在示例应用程序中,我可以看到一个属性让我们说“X”但是以编程方式我无法通过在对象后面放置点(。)来访问它变量。我也用反射来获得属性,但没有成功。有人建议它可能是一个动态的属性。我发现无法检查给定对象或该对象的任何成员是否是动态的?
请建议一种访问该属性的方法。
PropertGrid控件能够显示上述属性并允许更改值,但无法以编程方式访问此属性。
答案 0 :(得分:1)
解决此问题的方法是直接查看已知具有动态属性的类型的生成的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();
}
}