字符串变量读取属性的扩展方法
Extension method for string variable to read attribute
我有一个带有字符串常量的 class:
public static class Days
{
[Description("Wow!")]
public const string Mon = "Hi!";
}
我发现 it is possible for enum
to have an extension method to read Description
attribute:
using System.ComponentModel;
public enum Days
{
[Description("Wow!")]
Mon
}
enum
的扩展方法:
public static string ToName(this Enum value)
{
var attribute = value.GetAttribute<DescriptionAttribute>();
return attribute == null ? value.ToString() : attribute.Description;
}
然后这样称呼它:
Days.Mon.ToName()
是否可以为 string
编写一个扩展方法以从 Mon
字符串变量的 Description
属性中获取 Wow!
并像那样调用字符串的扩展方法?
string description = Days.Mon.ToName(); // Output: "Wow!"
这不是那么简单,尽管有一些 hacky 的替代方案,我将在这个答案中解释其中最不 hacky 的(至少在我看来)。
首先,您无法将其作为 string
的扩展方法,原因很简单,因为无法从 string
中获取 FieldInfo
对象。但是,有一种方法可以从字段的类型和名称中获取 FieldInfo
对象。
您可以定义一个将这些作为参数并以这种方式获取属性的函数:
static string GetName<T>(string fieldName)
{
var field = typeof(T).GetField(fieldName);
if (field == null) // Field was not found
throw new ArgumentException("Invalid field name", nameof(fieldName));
var attribute = field.GetCustomAttribute<DescriptionAttribute>();
return attribute == null ? (string) field.GetRawConstantValue() : attribute.Description;
}
请记住,这仅适用于类型为 string
的字段(如果该字段上没有 DescriptionAttribute
)。如果您需要它与更多人一起工作,则需要对其进行调整。这也仅适用于 public
字段。同样,如果您需要它与更多人一起工作,则需要对其进行调整。
有了之后,你可以像这样使用它:
GetName<Days>(nameof(Days.Mon))
编辑:
如果您需要将它与静态 class 一起使用,您可以通过将其作为普通参数传递来绕过类型参数约束。以下函数执行此操作:
static string GetName(Type type, string fieldName)
{
var field = type.GetField(fieldName);
if (field == null) // Field was not found
throw new ArgumentException("Invalid field name", nameof(fieldName));
var attribute = field.GetCustomAttribute<DescriptionAttribute>();
return attribute == null ? (string)field.GetRawConstantValue() : attribute.Description;
}
你可以这样使用:GetName(typeof(Days), nameof(Days.Mon))
我有一个带有字符串常量的 class:
public static class Days
{
[Description("Wow!")]
public const string Mon = "Hi!";
}
我发现 it is possible for enum
to have an extension method to read Description
attribute:
using System.ComponentModel;
public enum Days
{
[Description("Wow!")]
Mon
}
enum
的扩展方法:
public static string ToName(this Enum value)
{
var attribute = value.GetAttribute<DescriptionAttribute>();
return attribute == null ? value.ToString() : attribute.Description;
}
然后这样称呼它:
Days.Mon.ToName()
是否可以为 string
编写一个扩展方法以从 Mon
字符串变量的 Description
属性中获取 Wow!
并像那样调用字符串的扩展方法?
string description = Days.Mon.ToName(); // Output: "Wow!"
这不是那么简单,尽管有一些 hacky 的替代方案,我将在这个答案中解释其中最不 hacky 的(至少在我看来)。
首先,您无法将其作为 string
的扩展方法,原因很简单,因为无法从 string
中获取 FieldInfo
对象。但是,有一种方法可以从字段的类型和名称中获取 FieldInfo
对象。
您可以定义一个将这些作为参数并以这种方式获取属性的函数:
static string GetName<T>(string fieldName)
{
var field = typeof(T).GetField(fieldName);
if (field == null) // Field was not found
throw new ArgumentException("Invalid field name", nameof(fieldName));
var attribute = field.GetCustomAttribute<DescriptionAttribute>();
return attribute == null ? (string) field.GetRawConstantValue() : attribute.Description;
}
请记住,这仅适用于类型为 string
的字段(如果该字段上没有 DescriptionAttribute
)。如果您需要它与更多人一起工作,则需要对其进行调整。这也仅适用于 public
字段。同样,如果您需要它与更多人一起工作,则需要对其进行调整。
有了之后,你可以像这样使用它:
GetName<Days>(nameof(Days.Mon))
编辑:
如果您需要将它与静态 class 一起使用,您可以通过将其作为普通参数传递来绕过类型参数约束。以下函数执行此操作:
static string GetName(Type type, string fieldName)
{
var field = type.GetField(fieldName);
if (field == null) // Field was not found
throw new ArgumentException("Invalid field name", nameof(fieldName));
var attribute = field.GetCustomAttribute<DescriptionAttribute>();
return attribute == null ? (string)field.GetRawConstantValue() : attribute.Description;
}
你可以这样使用:GetName(typeof(Days), nameof(Days.Mon))