【问题标题】:Is there a way for me to access a C# class attribute?有没有办法让我访问 C# 类属性?
【发布时间】:2016-10-18 10:18:34
【问题描述】:

我有办法访问 C# 类属性吗?

例如,如果我有以下课程:

...
[TableName("my_table_name")]
public class MyClass
{
    ...
}

我可以这样做吗:

MyClass.Attribute.TableName => my_table_name

谢谢!

【问题讨论】:

标签: c# petapoco


【解决方案1】:

您可以为此使用Attribute.GetCustomAttribute 方法:

var tableNameAttribute = (TableNameAttribute)Attribute.GetCustomAttribute(
    typeof(MyClass), typeof(TableNameAttribute), true);

但是这对我来说太冗长了,通过下面的小扩展方法,你真的可以让你的生活变得更轻松:

public static class AttributeUtils
{
    public static TAttribute GetAttribute<TAttribute>(this Type type, bool inherit = true) where TAttribute : Attribute
    {
        return (TAttribute)Attribute.GetCustomAttribute(type, typeof(TAttribute), inherit);
    }
}

所以你可以简单地使用

var tableNameAttribute = typeof(MyClass).GetAttribute<TableNameAttribute>();

【讨论】:

    【解决方案2】:

    您可以使用反射来获取它。这是一个完整的示例:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication2
    {
        public class TableNameAttribute : Attribute
        {
            public TableNameAttribute(string tableName)
            {
                this.TableName = tableName;
            }
            public string TableName { get; set; }
        }
    
        [TableName("my_table_name")]
        public class SomePoco
        {
            public string FirstName { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var classInstance = new SomePoco() { FirstName = "Bob" };
                var tableNameAttribute = classInstance.GetType().GetCustomAttributes(true).Where(a => a.GetType() == typeof(TableNameAttribute)).Select(a =>
                {
                    return a as TableNameAttribute;
                }).FirstOrDefault();
    
                Console.WriteLine(tableNameAttribute != null ? tableNameAttribute.TableName : "null");
                Console.ReadKey(true);
            }
        }    
    }
    

    【讨论】:

      【解决方案3】:

      这是一个扩展,它通过扩展 object 为您提供属性帮助器,从而使其更容易。

      namespace System
      {
          public static class ReflectionExtensions
          {
              public static T GetAttribute<T>(this object classInstance) where T : class
              {
                  return ReflectionExtensions.GetAttribute<T>(classInstance, true);
              }
              public static T GetAttribute<T>(this object classInstance, bool includeInheritedAttributes) where T : class
              {
                  if (classInstance == null)
                      return null;
      
                  Type t = classInstance.GetType();
                  object attr = t.GetCustomAttributes(includeInheritedAttributes).Where(a => a.GetType() == typeof(T)).FirstOrDefault();
                  return attr as T;
              }
          }
      }
      

      这会将我之前的答案变成:

      class Program
      {
          static void Main(string[] args)
          {
              var classInstance = new SomePoco() { FirstName = "Bob" };
              var tableNameAttribute = classInstance.GetAttribute<TableNameAttribute>();
      
              Console.WriteLine(tableNameAttribute != null ? tableNameAttribute.TableName : "null");
              Console.ReadKey(true);
          }
      }   
      

      【讨论】:

      • 为了防止命名空间冲突,最好不要扩展 System 命名空间,而是使用您自己的命名空间,并记住在您希望扩展工作时包含命名空间。这样做,它们将在您使用 System 命名空间的任何地方工作,但将来很容易与 Microsoft 或第三方依赖项的 System 签名发生冲突。
      猜你喜欢
      • 2022-08-02
      • 1970-01-01
      • 1970-01-01
      • 2022-08-23
      • 1970-01-01
      • 2022-09-22
      • 2010-09-07
      • 2011-04-15
      • 1970-01-01
      相关资源
      最近更新 更多