[英]How to define an attribute to get the property name on which it is declared in c#?
在我的数据库中,所有表都有状态字段,但每个表对该列都有不同的名称。 例如,用户表有 user_status,分支表有 branch_status。 不同表的所有这些列都具有相同的值。 我已经为所有人创建了 POCO 实体,并希望创建一个通用函数来对指定的 POCO 实体类的状态字段执行查询。 所以我想创建一个属性,说明这将是指定实体类的状态字段。
因此,属性将为我提供声明它的属性名称。 该属性将仅在类中的单个属性上声明。 到目前为止,我已经完成了以下操作并且它正在工作,但想知道实现相同目标的有效方法。 下面是我的代码:
自定义属性:
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class StatusFieldAttribute : Attribute
{
}
宣言
public class UserTable
{
public int UserId{ get; set; }
[StatusField]
public int UserStatus { get; set; }
}
public class BranchTable
{
public int BranchId{ get; set; }
[StatusField]
public int BranchStatus { get; set; }
}
我想从具有 StatusField 属性的 UserTable 和 BranchTable 中获取属性名称。 我取得了与以下相同的成绩:
Type type = typeof(UserTable);
string statusFieldName = type.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(StatusFieldAttribute))).FirstOrDefault().Name;
上面的代码给出了正确的输出为 UserStatus。 但是有没有一种有效的方法可以使用以下内容来实现相同的目标:
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class StatusFieldAttribute : Attribute
{
public StatusFieldAttribute([CallerMemberName] string propertyName = null)
{
StatusFieldName = propertyName;
}
public string StatusFieldName { get; }
}
并访问 StatusFieldName 以获取在特定类中声明 StatusField 属性的属性的名称。
一种方法是定义一个标记接口(在 C# 8 之前),并定义一个扩展方法来检索正确的状态字段,如下所示:
interface IStatusFieldMarker
{
}
static class Extensions
{
public static string GetStatusFieldName(this IStatusFieldMarker t) =>
t.GetType()
.GetProperties()
.Single(p => Attribute.IsDefined(p, typeof(StatusFieldAttributeAttribute)))
.Name;
// optional getter/setter
public static int GetStatus(this IStatusFieldMarker t) =>
(int)(t.GetType()
.GetProperty(GetStatusFieldName(t))
.GetValue(t));
public static void SetStatus(this IStatusFieldMarker t, int value)
{
t.GetType()
.GetProperty(GetStatusFieldName(t))
.SetValue(t, value);
}
}
然后用接口标记 POCO 对象:
class Branch : IStatusFieldMarker
{
[StatusFieldAttribute]
public int BranchStatus { get; set; }
}
class User : IStatusFieldMarker
{
[StatusFieldAttribute]
public int UserStatus { get; set; }
}
然后可以调用GetStatusFieldName
扩展方法来获取字段名称:
Branch b = new Branch() { BranchStatus = 3 };
User u = new User() { UserStatus = 1 };
Console.WriteLine(b.GetStatusFieldName()); // prints BranchStatus
Console.WriteLine(u.GetStatusFieldName()); // prints UserStatus
Console.WriteLine(b.GetStatus()); // prints 3
Console.WriteLine(u.GetStatus()); // prints 1
我只是创建了下面的函数来获取状态名称
public static string GetStatusField<T>(this T type) where T : Type
{
PropertyInfo propertyInfo = type.GetProperties().FirstOrDefault(prop => Attribute.IsDefined(prop, typeof(StatusFieldAttribute)));
if (propertyInfo == null)
{
Log.Error($"StatusFieldAttribute not found in {type.Name} ");
throw new Exception($"StatusFieldAttribute not found in { type.Name } ");
}
else
return propertyInfo.Name;
}
并将该函数调用为
Type type = typeof(UserTable);
string statusFieldName = type.GetStatusField();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.