如何从静态 class 获取常量到列表 <SelectListItem>

How to get constants from a static class into a List<SelectListItem>

我有一个带有常量的静态 class,我想将其存储在列表中以便在 DropDown

中使用
public static class DateFormatConstant
{
    [Display(Name = "DD/MM/YYYY")]
    public const string DayMonthYear = "dd/MM/yyyy";
    [Display(Name = "MM/DD/YYYY")]
    public const string MonthDayYear = "MM/dd/yyyy";
    [Display(Name = "YYYY/MM/DD")]
    public const string YearMonthDay = "yyyy/MM/dd";
    [Display(Name = "MM/DD/YY")]
    public const string MonthDayTwoDigitYear = "MM/dd/yy";
}

有没有办法让他们进入List<SelectListItem>

如果你想自动完成,你需要使用反射:

IEnumerable<SelectListItem> fields = typeof(DateFormatConstant).GetFields(BindingFlags.Public | BindingFlags.Static)
    .Where(f => f.IsLiteral && !f.IsInitOnly) // all the constant fields
    .Select(f => new SelectListItem() {    //convert to SelectListItem
            Text = ((string)f.GetRawConstantValue()).ToUpper(),
            Value = (string)f.GetRawConstantValue()
        });

利用反射是一个很好的方法。但是由于您已经使用 Display 属性装饰常量,我将扩展此解决方案以使用该属性。请注意,我在这里使用 LINQ 的查询语法而不是其他答案中的方法语法。

这是我的代码:

var selectLisItems =
    from f in typeof(DateFormatConstant).GetFields(BindingFlags.Public | BindingFlags.Static)
    where f.IsLiteral && f.FieldType == typeof(string)
    from a in f.CustomAttributes
    where a.AttributeType == typeof(DisplayAttribute)
    let na = a.NamedArguments.First(x => x.MemberName == nameof(DisplayAttribute.Name))
    select new SelectListItem
    {
        Text = (string)na.TypedValue.Value,
        Value = (string)f.GetRawConstantValue()
    };

var list = selectLisItems.ToList();

它究竟有什么作用?让我们看看查询的部分。

    from f in typeof(DateFormatConstant).GetFields(BindingFlags.Public | BindingFlags.Static)
    where f.IsLiteral && f.FieldType == typeof(string)

这里我从 DateFormatConstant class 中选择 string.

类型的所有常量
    from a in f.CustomAttributes
    where a.AttributeType == typeof(DisplayAttribute)

现在我限制为实际具有 Display 属性的常量。注意这里的"real"类型是DisplayAttribute

    let na = a.NamedArguments.First(x => x.MemberName == nameof(DisplayAttribute.Name))

下一步是检查属性的参数并搜索 Name。我可以在这里安全地使用 First 因为我已经限制了 DisplayAttribute 类型并且因此知道它有一个 Name 属性.

    select new SelectListItem
    {
        Text = (string)na.TypedValue.Value,
        Value = (string)f.GetRawConstantValue()
    };

var list = selectLisItems.ToList();

最后我从属性和字段构造 SelectListItem 并从查询创建所需的 List<SelectListItem>

注意: 所有这些都假设您希望 所有 字符串常量来自 class 包含在列表中。如果您的 class 包含更多应该放在不同列表中的常量,您可以使用 Display 属性的 GroupName 属性 将常量组合在一起。我将把它留作相应扩展代码的练习。