运行时,如何测试属性是否为只读?

9
我正在自动生成代码,根据配置创建一个winform对话框(包含文本框、日期选择等)。这些对话框中的控件是从已保存的数据集中填充的,需要为各个控件对象(自定义或其他)设置和获取属性。
//Upon opening of form - populate control properties with saved values
MyObject.Value = DataSource.GetValue("Value");

//Upon closing of form, save values of control properties to dataset.
DataSource.SetValue("Value") = MyObject.Value;

现在这很好,但是只读属性怎么办?我希望保存属性的结果,但需要知道何时不生成试图填充它的代码。
//Open form, attempt to populate control properties.
//Code that will result in 'cannot be assigned to -- it is read only'
MyObject.HasValue = DataSource.GetValue("HasValue");
MyObject.DerivedValue = DataSource.GetValue("Total_SC2_1v1_Wins");

//Closing of form, save values. 
DataSource.SetValue("HasValue") = MyObject.HasValue;

请记住,直到运行时我才知道我实例化的对象类型。

如何在运行时识别只读属性?


在我看来,如果一个属性是只读的,用户就不能从UI表单修改它。目前似乎所有属性都可以在表单上被编辑,并且你在保存时检查它们? - Cheng Chen
您的陈述是正确的,但这是自动生成的代码。错误发生在编译时。只有当生成的代码从保存的值填充控件属性时,才会出现“无法分配”的情况,因此意外地将已保存的值分配给只读属性。 - MoSlo
4个回答

8

使用PropertyDescriptor,检查IsReadOnly

使用PropertyInfo,检查CanWrite(对于CanRead同样如此)。

PropertyInfo的情况下,您可能还想检查[ReadOnly(true)](但这已经由PropertyDescriptor处理):

 ReadOnlyAttribute attrib = Attribute.GetCustomAttribute(prop,
       typeof(ReadOnlyAttribute)) as ReadOnlyAttribute;
 bool ro = !prop.CanWrite || (attrib != null && attrib.IsReadOnly);

在我看来,PropertyDescriptor是更好的模型选择;它将允许自定义模型。


6
我注意到当使用 PropertyInfo 时,即使 setter 是私有的,CanWrite 属性也为 true。这个简单的检查对我很有用:
bool IsReadOnly = prop.SetMethod == null || !prop.SetMethod.IsPublic;

2
此外 - 请参见微软页面。 (链接)
using System.ComponentModel;

// Get the attributes for the property.

AttributeCollection attributes = 
   TypeDescriptor.GetProperties(this)["MyProperty"].Attributes;

// Check to see whether the value of the ReadOnlyAttribute is Yes.
if(attributes[typeof(ReadOnlyAttribute)].Equals(ReadOnlyAttribute.Yes)) {
   // Insert code here.
}

0

我需要在不同的类中使用它,因此我创建了这个通用函数:

public static bool IsPropertyReadOnly<T>(string PropertyName)
{
    MemberInfo info = typeof(T).GetMember(PropertyName)[0];

    ReadOnlyAttribute attribute = Attribute.GetCustomAttribute(info, typeof(ReadOnlyAttribute)) as ReadOnlyAttribute;

    return (attribute != null && attribute.IsReadOnly);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接