需要反射帮助:GetProperty返回意外类型

时间:2017-10-16 13:14:51

标签: c# visual-studio reflection casting

我正在使用.NET PropertyGrid对象。在运行时,我需要检查PropertyGrid的PropertyGridView.SelectedGridEntry对象的Label属性。

第一个问题是SelectedGridEntry不是公共属性 - 它似乎是内部的。所以我需要求助于反思。我相信我使用这一简单的代码行成功获得了一个PropertyGridView实例对象:

var gridView = PropertyGrid.Controls[2];

(让我们接受可疑的假设,即PropertyGrid.Controls 1上的PropertyGridView对象始终可用。)

暂时不反思,我在运行时使用Visual Studio 2017调试器来检查PropertyGrid的PropertyGridView对象。这是图像:

enter image description here

此图显示gridView对象具有名为SelectedGridEntry的属性。请注意,其类型为 System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry 。不幸的是,我无法转换为PropertyDescriptorGridEntry类型,因为我无法访问System.Windows.Forms.PropertyGridInternal命名空间(微软似乎没有提供它,似乎)。

为了获取SelectedGridEntry对象,我使用了以下代码行:

var selectedGridEntry = PropertyGrid.Controls[2].GetType().GetProperty("SelectedGridEntry", BindingFlags.Instance | BindingFlags.NonPublic);

不幸的是,这会返回 GridEntry 类型的变种:

enter image description here

我不明白为什么通过反射获得的类型不是预期的 PropertyDescriptorGridEntry 类型。由于我似乎无法访问我需要的命名空间,因此我无法将 GridEntry 对象转换为 PropertyDescriptorGridEntry 对象。

如何将局部变量分配给 SelectedGridEntry 对象,并确保它具有正确的 PropertyDescriptorGridEntry 类型?我觉得如果我成功了,我就可以获得该对象的Label属性值......

1 个答案:

答案 0 :(得分:1)

属性可以返回类型相同的对象,或从派生的属性,该属性的类型。机制允许这样做,即Object-oriented programming中称为Polymorphism

类型PropertyDescriptorGridEntry的继承链如下所示:

Object => GridItem => GridEntry => PropertyDescriptorGridEntry

因此SelectedGridEntry类型的属性GridEntry可以返回PropertyDescriptorGridEntry类型的对象,因为它来自GridEntry。这也意味着,该对象继承了它的父类型的所有属性,包括Label属性(在GridItem类中定义)。因此,事件PropertyDescriptorGridEntry类型是System.Windows.Forms程序集的内部类型,并且在不相关的情况下不公开显示,因为您可以将此对象强制转换为GridItem(这是公共的)并读取内容Label来自那里:

var selectedGridEntry = PropertyGrid.Controls[2].GetType().GetProperty("SelectedGridEntry", BindingFlags.Instance | BindingFlags.NonPublic);
var gridEntry = (GridItem)selectedGridEntry.GetValue(PropertyGrid.Controls[2‌​]);
var label = gridEntry.Label;