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

时间:2011-03-09 09:34:20

标签: c# properties

我自动生成代码,根据配置(textboxes,dateTimePickers等)创建一个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;

现在这一切都很好,但readOnly属性是什么?我希望保存属性的结果,但需要知道何时不生成将尝试填充它的代码。

//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;

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

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

4 个答案:

答案 0 :(得分:7)

使用PropertyDescriptor,检查IsReadOnly

使用PropertyInfo,检查CanWrite(和CanRead,就此而言)。

对于[ReadOnly(true)],您可能还想检查PropertyInfo(但已经使用PropertyDescriptor处理了这一点):

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

IMO,PropertyDescriptor是一个更好的模型在这里使用;它将允许自定义模型。

答案 1 :(得分:3)

我注意到在使用PropertyInfo时,即使setter是私有的,CanWrite属性也是如此。这个简单的检查对我有用:

bool IsReadOnly = prop.SetMethod == null || !prop.SetMethod.IsPublic;

答案 2 :(得分:2)

另外 - See Microsoft Page

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.
}

答案 3 :(得分: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);
}