2009-07-09 72 views
1

我们有一些可能导出为各种格式的东西。目前我们已经通过枚举喜欢这代表这些格式:替换需要翻译和枚举的枚举

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

问题是,这些必须被枚举,他们还需要在用户界面翻译或说明。目前我通过创建两个扩展方法解决了这个问题他们工作,但我真的不喜欢他们或解决方案...他们觉得有点臭。问题是我真的不知道如何做得更好。有没有人有任何好的选择?这两种方法:

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(", "); 
    } 

也许这是这样做的方式,但我有一种感觉,必须有更好的方法来做到这一点。我怎么能重构这个?

+0

难道你不需要本地化这些字符串吗?如果是这样,他们将会在资源文件中,所以将它们放在代码中没有意义。 – 2009-07-09 08:54:47

+0

是的。但仍然需要一些连接资源键和枚举的方式。 – Svish 2009-07-09 09:28:45

回答

5

你可以使用格式方法中说明,以避免在多个地方做所有的位操作,像这样:

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()); 
} 

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

1

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

public class FormatDescription : Attribute 
{ 
    public string Description { get; private set; } 

    public FormatDescription(string description) 
    { 
     Description = description; 
    } 
} 

然后在Describe函数中使用Reflection。 这种方法的唯一好处是在一个地方进行定义和描述。

+0

您可能希望在运行时缓存查找,因为它们不会更改,并且使用反射来重复调用Describe将会代价高昂。 – adrianbanks 2009-07-09 09:11:52

+0

虽然这将很难本地化,不是吗?因为据我所知,当使用属性时,你不能真正查找资源字符串等。 – Svish 2009-07-09 09:30:22

0

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

你可以写,读取指定的属性,看看他们在你的资源的类型转换器。因此,您可以毫不费力地获得显示名称的多语言支持。

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

增加:

滚动在链接的职位,做什么是需要全面支持的一部分类型转换器的实现了。

这将支持您同时具有多种语言的应用程序,不仅代码名称 - >英文名称。

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