如何在C#中从子类型树中声明atrribute的类型

时间:2015-05-05 11:19:27

标签: c# custom-attributes

我花了很多时间来找到如何获得在子类型层次结构中声明属性的类型,但是还没有找到任何方法,希望任何人都知道如何帮助我。

示例我们有一些东西如下:

如果需要,我有一个属性类来定义表的名称

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class TableBaseAttribute : Attribute
{
    public string Name;
}

然后我可以用它作为

[TableBase] // when not assign Name, will get name of the type which declare attribute, in this case is 'Customer'
class Customer
{

}

class CustomerProxy : Customer
{

}

[TableBase(Name = "_USER")]
class User
{

}

class UserRBAC : User
{

}

class UserRBACProxy : UserRBAC
{

}

所以现在,如何解决这个问题

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Table of CustomerProxy is : {0}", GetTableNameFromType(typeof(CustomerProxy)));
        Console.WriteLine("Table of UserProxy is : {0}", GetTableNameFromType(typeof(UserRBACProxy)));
    }

    static string GetTableNameFromType(Type type)
    {
        // what go here to get string of "Customer" for type = CustomerProxy
        //              to get string of "_USER" for type = UserRBACProxy

        TableBaseAttribute tableBaseA = (TableBaseAttribute)typeof(CustomerProxy).GetCustomAttributes(type, true)[0];

        string ret = null;
        if (string.IsNullOrEmpty(tableBaseA.Name))
            ret = ???
        else
            ret = tableBaseA.Name;

        return ret;
    }
}

2 个答案:

答案 0 :(得分:0)

如果未指定属性覆盖,则可以使用该类型的Name属性,这将仅为您提供类名

ret = String.IsNullOrEmpty(tableBaseA.Name) ? type.Name : tableBaseA.Name;

我刚刚意识到上述内容在提取TableBase修饰类型类名称的上下文中不起作用,而是采用当前类型类名称。在这种情况下,您需要按照继承树的方式来查找基类

var baseType = type.BaseType;
while (baseType != null)
{
    var attrs = baseType.GetCustomAttributes(typeof(TableBaseAttribute), false);
    if (attrs.Length > 0) 
    {
        ret = baseType.Name;
        break;
    }
}

答案 1 :(得分:0)

我不确定我是否理解正确。您想要声明属性的类型的名称,对吗?如果是这样,这应该有效:

    static string GetTableNameFromType(Type type)
    {
        // what go here to get string of "Customer" for type = CustomerProxy
        //              to get string of "_USER" for type = UserRBACProxy

        TableBaseAttribute tableBaseA = (TableBaseAttribute)type.GetCustomAttributes(typeof(TableBaseAttribute), true)[0];

        string ret = null;
        if (string.IsNullOrEmpty(tableBaseA.Name))
        {
            do
            {
                var attr = type.GetCustomAttributes(typeof(TableBaseAttribute), false);
                if (attr.Length > 0)
                {
                    return type.Name;
                }
                else
                {
                    type = type.BaseType;
                }
            } while (type != typeof(object));
        }
        else
        {
            ret = tableBaseA.Name;
        }

        return ret;
    }