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

时间:2022-11-27 14:26:01

I spend a lot of times to find how to get the type which declare the attribute in sub type hierarchy, but no find out any way yet, hope any one know how to help me.

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

Example we have some stuffs as below:

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

I have a attribute class to define name of table if needed

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

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

then i can use it as

然后我可以用它作为

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

}

class CustomerProxy : Customer
{

}

and

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

}

class UserRBAC : User
{

}

class UserRBACProxy : UserRBAC
{

}

so now, how to solve this

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

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 个解决方案

#1


I am not sure I understand you correctly. You want the name of the type on which the attribute is declared, right? If so, this should work:

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

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

#2


You can use the Name property of the type when no attribute override is specified, this will give you the class name only

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

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

I just realised that the above would not work in the context of pulling the TableBase decorated type class name but instead take the current type class name. In that case, you will need to work your way up the inheritance tree to find that base class

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

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

#1


I am not sure I understand you correctly. You want the name of the type on which the attribute is declared, right? If so, this should work:

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

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

#2


You can use the Name property of the type when no attribute override is specified, this will give you the class name only

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

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

I just realised that the above would not work in the context of pulling the TableBase decorated type class name but instead take the current type class name. In that case, you will need to work your way up the inheritance tree to find that base class

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

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