【问题标题】:Replacement of enum that requires translation and enumeration替换需要翻译和枚举的枚举
【发布时间】:2009-07-09 08:36:03
【问题描述】:

我们有一些可以导出为各种格式的东西。目前我们有这些格式由这样的枚举表示:

[Flags]
public enum ExportFormat
{
    None = 0x0,
    Csv = 0x1,
    Tsv = 0x2,
    Excel = 0x4,
    All = Excel | Csv | Tsv
}

问题是这些必须枚举,并且它们还需要在 ui 中进行翻译或描述。目前我通过创建两个扩展方法解决了这个问题。他们工作,但我真的不喜欢他们或解决方案......他们觉得有点臭。问题是我真的不知道如何才能做得更好。有没有人有任何好的选择?这是两种方法:

    public static IEnumerable<ExportFormat> Formats(this ExportFormat exportFormats)
    {
        foreach (ExportFormat e in Enum.GetValues(typeof (ExportFormat)))
        {
            if (e == ExportFormat.None || e == ExportFormat.All)
                continue;

            if ((exportFormats & e) == e)
                yield return e;
        }
    }

    public static string Describe(this ExportFormat e)
    {
        var r = new List<string>();

        if ((e & ExportFormat.Csv) == ExportFormat.Csv)
            r.Add("Comma Separated Values");

        if ((e & ExportFormat.Tsv) == ExportFormat.Tsv)
            r.Add("Tab Separated Values");

        if ((e & ExportFormat.Excel) == ExportFormat.Excel)
            r.Add("Microsoft Excel 2007");

        return r.Join(", ");
    }

也许这就是这样做的方法,但我觉得必须有更好的方法来做到这一点。我该如何重构它?

【问题讨论】:

  • 你不需要本地化这些字符串吗?如果是这样,它们无论如何都会在资源文件中,因此将它们放在代码中的任何地方是没有意义的。
  • 是的。但仍需要某种方式将资源键与枚举连接起来。

标签: c# enums


【解决方案1】:

您可以使用 Describe 中的 Formats 方法来避免在多个位置执行所有位操作,如下所示:

private static Dictionary<ExportFormat, string> FormatDescriptions =
    new Dictionary<ExportFormat,string>()
{
    { ExportFormat.Csv, "Comma Separated Values" },
    { ExportFormat.Tsv, "Tab Separated Values" },
    { ExportFormat.Excel, "Microsoft Excel 2007" },            
};

public static string Describe(this ExportFormat e)
{
    var formats = e.Formats();
    var descriptions = formats.Select(fmt => FormatDescriptions[fmt]);

    return string.Join(", ", descriptions.ToArray());
}

这样,如上所述,很容易合并来自外部源或本地化的字符串描述。

【讨论】:

    【解决方案2】:

    我想到的唯一其他方法是使用 System.Attribute 类。

    public class FormatDescription : Attribute
    {
        public string Description { get; private set; }
    
        public FormatDescription(string description)
        {
            Description = description;
        }
    }
    

    然后在您的描述函数中使用反射。 这种方法的唯一好处是在一个地方有定义和描述。

    【讨论】:

    • 您可能希望在运行时缓存查找,因为它们不会更改,并且使用反射来重复调用 Describe 的成本很高。
    • 这很难本地化,不是吗?因为据我所知,您在使用属性时无法真正查找资源字符串等..
    【解决方案3】:

    骗子:How do I have an enum bound combobox with custom string formatting for enum values?

    您可以编写一个读取指定属性的 TypeConverter,以便在您的资源中查找它们。因此,您可以毫不费力地获得对显示名称的多语言支持。

    查看 TypeConverter 的 ConvertFrom/ConvertTo 方法,并使用反射来读取枚举字段的属性。

    加法:

    在链接的帖子中向下滚动以获取 TypeConverter 的实现,它可以完成完全支持所需的部分功能。

    这将支持您同时使用多种语言的应用程序,而不仅仅是代号 -> 英文名称。

    请记住,这只是显示名称,而不是存储的值。您应该始终存储代码名称或整数值,以支持具有不同语言环境的用户使用相同的数据。

    【讨论】:

    • 很好地抓住了相关问题(骗人,我不知道),但我倾向于同意该问题的更高评级的答案。如果您制作自定义 TypeConverter,那么您有效地更改了该枚举作为字符串的表示方式,可能会影响诸如序列化之类的事情,对吧?我确实喜欢 GetDescription 和 NicenessComboBoxItem 的想法。
    猜你喜欢
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 2018-06-23
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多