如何从 C# 中的子类型树获取属性的声明类型
How to get declaring type of an atrribute from sub types tree in C#
我花了很多时间寻找如何获取在子类型层次结构中声明属性的类型,但还没有找到任何方法,希望有人知道如何帮助我。
例如我们有一些东西如下:
如果需要,我有一个属性 class 来定义 table 的名称
[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;
}
}
当没有指定属性覆盖时,您可以使用类型的 Name 属性,这只会给您 class 名称
ret = String.IsNullOrEmpty(tableBaseA.Name) ? type.Name : tableBaseA.Name;
我刚刚意识到以上内容在拉动 TableBase
修饰类型 class 名称的上下文中不起作用,而是采用 current 类型 class名字。在这种情况下,您将需要沿着继承树向上查找基数 class
var baseType = type.BaseType;
while (baseType != null)
{
var attrs = baseType.GetCustomAttributes(typeof(TableBaseAttribute), false);
if (attrs.Length > 0)
{
ret = baseType.Name;
break;
}
}
我不确定我是否理解正确。您想要声明属性的类型的名称,对吗?如果是这样,这应该有效:
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;
}
我花了很多时间寻找如何获取在子类型层次结构中声明属性的类型,但还没有找到任何方法,希望有人知道如何帮助我。
例如我们有一些东西如下:
如果需要,我有一个属性 class 来定义 table 的名称
[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;
}
}
当没有指定属性覆盖时,您可以使用类型的 Name 属性,这只会给您 class 名称
ret = String.IsNullOrEmpty(tableBaseA.Name) ? type.Name : tableBaseA.Name;
我刚刚意识到以上内容在拉动 TableBase
修饰类型 class 名称的上下文中不起作用,而是采用 current 类型 class名字。在这种情况下,您将需要沿着继承树向上查找基数 class
var baseType = type.BaseType;
while (baseType != null)
{
var attrs = baseType.GetCustomAttributes(typeof(TableBaseAttribute), false);
if (attrs.Length > 0)
{
ret = baseType.Name;
break;
}
}
我不确定我是否理解正确。您想要声明属性的类型的名称,对吗?如果是这样,这应该有效:
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;
}