【问题标题】:C# Buddy Classes / Meta Data and ReflectionC# Buddy 类/元数据和反射
【发布时间】:2010-03-02 16:10:06
【问题描述】:

我正在尝试使用反射来检查给定类的属性是否具有 ReadOnly 属性集。我使用的类是 MVC 视图模型(对元数据使用部分“伙伴”类。

 public partial class AccountViewModel  
{
    public virtual Int32 ID { get; set; } 
    public virtual decimal Balance { get; set; }    

} 
[MetadataType(typeof(AccountViewModelMetaData))]
public partial class AccountViewModel  
{
    class AccountViewModelMetaData
    {
        [DisplayName("ID")]
        public virtual Int32 ID { get; set; }

        [DisplayName("Balance")]
        [DataType(DataType.Currency)] 
        [ReadOnly(true)]
        public virtual decimal Balance { get; set; }

    }
}

我想检查“Balance”是否具有 ReadOnly 属性。如果我在 AccountViewModel 的 Balance 属性上设置 ReadOnly 属性,我可以这样检索它:

Type t = typeof(AccountViewModel);
PropertyInfo pi = t.GetProperty("Balance");  
bool isReadOnly =  ReadOnlyAttribute.IsDefined(pi,typeof( ReadOnlyAttribute);

如果属性信息在元数据类上,我无法检索它。如何检查属性是否存在?我为我的所有视图模型定义了元数据类,并且需要一种通用的方法来检查元数据类的属性。

有什么建议吗?

【问题讨论】:

    标签: c# .net reflection attributes


    【解决方案1】:

    解决方案是使用GetCustomAttributes 获取元数据类型并检查这些属性...

    Type t = typeof(MyClass);
    PropertyInfo pi = t.GetProperty(PropertyName);  
    bool isReadOnly = ReadOnlyAttribute.IsDefined(pi, typeof(ReadOnlyAttribute));
    
    if (!isReadOnly)
    {
        //check for meta data class.
        MetadataTypeAttribute[] metaAttr = (MetadataTypeAttribute[])t.GetCustomAttributes(typeof(MetadataTypeAttribute),true);
    
        if (metaAttr.Length > 0)
        {
            foreach (MetadataTypeAttribute attr in metaAttr)
            {
                t = attr.MetadataClassType;
                pi = t.GetProperty(PropertyName);
    
                if (pi != null) isReadOnly = ReadOnlyAttribute.IsDefined(pi, typeof(ReadOnlyAttribute));
    
                if (isReadOnly) break;
            }
        }
    } 
    

    【讨论】:

    • 请注意,您正在检查该属性是否存在,而不是它已定义为 true。您是否考虑过如果属性定义为 [ReadOnlyAttribute(false)] 会发生什么?
    • 抱歉,无法理解您的解决方案。 :(
    【解决方案2】:

    下面是一个简短但有效的示例,请注意,我创建了嵌套类 internal 以便对外部可见。

    public partial class AccountViewModel
    {
        internal class AccountViewModelMetaData
        {
            public virtual Int32 ID { get; set; }
            [ReadOnlyAttribute(false)]
            public virtual decimal Balance { get; set; }
        }
    
        public virtual Int32 ID { get; set; }
        public virtual decimal Balance { get; set; }
    }
    class Program
    {
        public static void Main(string[] args)
        {
            Type metaClass = typeof(AccountViewModel.AccountViewModelMetaData);
    
            bool hasReadOnlyAtt = HasReadOnlyAttribute(metaClass, "Balance");
    
            Console.WriteLine(hasReadOnlyAtt);
        }
    
        private static bool HasReadOnlyAttribute(Type type, string property)
        {
            PropertyInfo pi = type.GetProperty(property);
    
            return ReadOnlyAttribute.IsDefined(pi, typeof(ReadOnlyAttribute));
        }
    }
    

    还要注意,这会检查属性是否存在。您可以在此示例中指定属性,但提供 false 的值。如果要检查属性是否为只读,不能只使用ReadOnlyAttribute.IsDefined方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-21
      相关资源
      最近更新 更多