Get private properties with TypeDescriptor
我想使用c中的typescriptor获取类的私有属性。
到目前为止的电话
1
| TypeDescriptor.GetProperties(myType); |
只返回公共的非静态属性。
我还没有找到一种方法来影响GetProperties或GetProvider方法,以强制它们返回除"默认"(公共、非静态)成员之外的其他成员。
请不要建议反射(我很清楚绑定标志),除非它给了我一个PropertyDescriptor对象。
- 我不知道在不使用反射的情况下,用TypeDescriptor可以做什么。你不想用反省的原因是什么?
- 如果需要调用,则typescriptor要快得多。
- 不幸的是,它不能用typescriptor完成。你需要依靠反思。
- 此外,如果需要外部访问,它应该是公共的,而不是私有的。
- @MarcGravell——所以当我说"不幸的是,不能用typedefector来完成。你需要反省一下。"我是对的。您可以使用使用反射的typescriptor的自定义扩展来执行此操作,这与使用现有的不带反射的typescriptor类不同(他希望这样做)。
- @多项式你是半正确的。您可以"教育"TypeDescriptor以返回OP想要的内容,但您需要使用反射来实现。但是,调用代码只知道TypeDescriptor和PropertyDescriptor。
- 取决于他所说的"更快"是什么意思。如果他是说在性能方面,仍然有一个反射开销。事实上,有更多的开销,因为您只是在用其他东西包装反射。如果他是说更干净,那我想可能是更干净一点?我看不出有什么不同。
- 我要使用的属性被标记为内部属性,出于某种原因,它们应该保持这样(但是为了快速修复,我们更改了最需要的几个属性的可见性)。
- 重新执行-默认情况下,它们大致相同;但是,通过typedescriptor,实际上可以将propertydescriptor设置为out perform propertyinfo(通过删除反射);这正是hyperdescriptor设置为do/cc@多项式的内容。
- 我们的案例场景中,我们有一个相同类型的对象集合,我们需要基于此信息生成SQL查询,并且我们有一个属性到列名的映射。因此,现在我们希望保持它的通用性,并将revoke与propertyinfo/propertydescriptor对象一起使用。测试显示,PropertyDescriptor的速度比以前快了很多倍。
- 在这种情况下,您可能真的会发现超描述符代码很有用,但是我个人会倾向于在*信息级别上看元编程;在dapper-dot-net中可以找到这样一个例子(在两个方向上),(有人为超描述符和dapper-dot-net编写了可怕的IL代码)。
要做到这一点,您必须编写并注册一个使用反射的自定义TypeDescriptionProvider。但是,您当然可以这样做——您甚至可以拥有与字段(而不是属性)实际对话的PropertyDescriptor实例。您可能还需要编写自己的bespke PropertyDescriptor实现,因为ReflectPropertyDescriptor是internal(您可以使用反射来获得它)。最终,您将不得不使用反射来实现,但是您可以实现TypeDescriptor.GetProperties(Type)返回您想要的PropertyDescriptor实例的要求。
您也可以对您控制之外的类型执行此操作。然而,应该强调的是,你的意图是不寻常的。
如果您使用的是.GetProperties(instance)重载,那么您也可以通过实现ICustomTypeDescriptor,这比完整的TypeDescriptionProvider更简单。
有关挂接定制提供程序的示例,请参见超描述符
- 我以前见过这个主意,看起来很可怕。你有例子吗?
- @班迪托布尼,我已经编辑了一个超描述符的例子-有什么用吗?
- 完美的是,我们已经有了一个超类型提供者的自定义实现(使用IL代码),我们已经更改了属性提取块的绑定标志,并使用了我们的自定义超类型提供者而不是默认的超类型提供者。
您可以创建自己的CustomPropertyDescriptor,从PropertyInfo获取信息。
最近我需要得到非公共属性的PropertyDescriptorCollection。
在我使用type.GetProperties(BindingFlags. Instance | BindingFlags.NonPublic)获得非公共属性之后,然后使用下面的类创建相应的PropertyDescriptor。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| class CustomPropertyDescriptor : PropertyDescriptor
{
PropertyInfo propertyInfo;
public CustomPropertyDescriptor(PropertyInfo propertyInfo)
: base(propertyInfo.Name, Array.ConvertAll(propertyInfo.GetCustomAttributes(true), o => (Attribute)o))
{
this.propertyInfo = propertyInfo;
}
public override bool CanResetValue(object component)
{
return false;
}
public override Type ComponentType
{
get
{
return this.propertyInfo.DeclaringType;
}
}
public override object GetValue(object component)
{
return this.propertyInfo.GetValue(component, null);
}
public override bool IsReadOnly
{
get
{
return !this.propertyInfo.CanWrite;
}
}
public override Type PropertyType
{
get
{
return this.propertyInfo.PropertyType;
}
}
public override void ResetValue(object component)
{
}
public override void SetValue(object component, object value)
{
this.propertyInfo.SetValue(component, value, null);
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
} |