【问题标题】:How to avoid repeating typing the same name multiple times within the same scope?如何避免在同一范围内多次重复输入相同的名称?
【发布时间】:2021-01-10 03:52:24
【问题描述】:

我有以下enum

public enum Event0Instance
{
    ClaimSent,
    RequestSent,
    ClaimResponseAqcuired,
    RequestResponseAqcuired,
    RequestRefusalAcquired,
}

有了这个enum,我制作了字典 Dictionary<Event0Instance, string>,其中string 值是每个枚举值的文本描述

public static Dictionary<Event0Instance, string> Event0Descriptions = 
  new Dictionary<Event0Instance, string>() 
  {
    {Event0Instance.ClaimSent, "Подана претензия" },
    {Event0Instance.RequestSent, "Подан запрос"},
    {Event0Instance.ClaimResponseAqcuired, "Получен ответ на претензию"},
    {Event0Instance.RequestResponseAqcuired, "Получен ответ на запрос"},
    {Event0Instance.RequestRefusalAcquired, "Получен отказ на запрос"}
  };

这里明显的问题是需要对每个条目重复 Event0Instance.。有 更多 enums,每个 比示例中的更大,如果我想为每个人创建一个 Dictionary,这是一个 巨大的代码重复.

在 VBA 语言中有一个 With / End Withconstruct 你可以这样使用:

With Person
    .FirstName = "John"
    .LastName = "Smith"
    .Age = 23
End With

C#中是否有类似的东西

【问题讨论】:

  • 您有什么理由不使用DisplayAttribute
  • 现代 IDE 提供了大量功能,可以以多种不同方式复制/粘贴值;)
  • @AnupSharma 我认为这对我现在的技能来说太过分了,此外,我不完全确定是将每个枚举值与一个字符串还是整个类相关联。跨度>
  • 实际上,输入 Enum 的所有名称是一种很好的做法,正如前面所说,IDE 可以帮助您一键重命名所有精度。但是对我来说,使用新的“case”语法而不是字典的方法,因为你将 100% 编写附加方法来使用你的字典。使用字典的唯一好主意是例如当您将数据作为 json 配置文件执行时,但不要忘记验证。

标签: c# enums


【解决方案1】:

为了跳过讨厌的Event0Instance.前缀,你可以试试using static构造,它的工作原理与with .. end with大致相似:

using static MyNamespace.Event0Instance;

...

public static Dictionary<Event0Instance, string> Event0Descriptions =
  new Dictionary<Event0Instance, string>() 
  {
    {ClaimSent, "Подана претензия" },
    {RequestSent, "Подан запрос"},
    {ClaimResponseAqcuired, "Получен ответ на претензию"},
    {RequestResponseAqcuired, "Получен ответ на запрос"},
    {RequestRefusalAcquired, "Получен отказ на запрос"}
  };

但是,我建议使用 attributes 并在 LinqReflection 的帮助下构建字典:

// Here we attribute each option with the desired description
public enum Event0Instance
{
    //TODO: do not hardcode the descriptions ("Подана претензия") 
    // but put resource name here
    [Description("Подана претензия")]
    ClaimSent,
    [Description("Подан запрос")]
    RequestSent,
    [Description("Получен ответ на претензию")]
    ClaimResponseAqcuired,
    [Description("Получен ответ на запрос")]
    RequestResponseAqcuired,
    [Description("Получен отказ на запрос")]
    RequestRefusalAcquired,
}

这是检查给定枚举并返回 {option, description} 字典的例程:

using System.Linq;
using System.Reflection;

...

// This routine inspects the enum given and return dictionary: {option, description} 
public static Dictionary<T, string> EnumDescriptions<T>() where T : Enum {
  return Enum
    .GetNames(typeof(T))
    .Select(name => new {
      name,
      value = Enum.Parse(typeof(T), name),
      member = typeof(T).GetMember(name)[0]
    })
    .ToDictionary(item => (T) (item.value),
                  item => item.member
                    .GetCustomAttributes<DescriptionAttribute>(true)
                    .FirstOrDefault()?.Description ?? item.name);
}

然后您可以在一行代码中构建字典:

// I doubt if you want public (!) Dictionary exposed to everyone;
// I guess readonly interface will be enough
public static readonly IReadOnlyDictionary<Event0Instance, string> Event0Descriptions = 
  EnumDescriptions<Event0Instance>();

【讨论】:

  • 具有属性的解决方案很好,但不能很好地扩展。如果您要支持多种语言,那将导致您的代码非常混乱,而且您可能不希望在源代码中包含所有翻译。
  • PMF,对,解决方案很好。至于翻译 - 属性可以包含对资源文件中条目的引用。
  • @PMF:如果我们想支持多种语言(比如问题中的英语、俄语、德语、法语等),我们可以在属性中存储的不是描述名称本身,而是 资源名称。那么我们要做的就是稍微修改EnumDescriptions例程
猜你喜欢
  • 1970-01-01
  • 2013-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多