枚举除字符串以外的返回类型?

由于枚举使用整数,我可以使用什么其他结构来给我类似enum的访问链接到名称的值:

[我知道这是错的,寻找替代方案]

private enum Project { Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"), Maintenance = new Guid("39D31D4-28EC-4832-827B-A11129EB2"), Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"), Sales = new Guid("A5690E7-1111-4AFB-B44D-1DF3AD66D435"), Replacement = new Guid("11E5CBA2-EDDE-4ECA-BDFD-63BDBA725C8C"), Modem = new Guid("6F686C73-504B-111-9A0B-850C26FDB25F"), Audit = new Guid("30558C7-66D9-4189-9BD9-2B87D11190"), Queries = new Guid("9985242-516A-4151-B7DD-851112F562") } 

编辑2014-07-20

这是对这个问题的新答案。 将Attribute类与辅助方法一起使用,定义枚举所需的额外属性。

  public enum MultiValueEnum { [FooAttribute("alpha", 20d, true)] First, [FooAttribute("beta", 40.91d, false)] Second, [FooAttribute("gamma", 1.2d, false)] Third, } public class FooAttribute : Attribute { internal FooAttribute(string name, double percentage, bool isGood) { this.Name = name; this.Percentage = (decimal)percentage; this.IsGood = isGood; } public string Name { get; private set; } public decimal Percentage { get; private set; } public bool IsGood { get; private set; } } public static TAttribute GetAttribute(this Enum value) where TAttribute : Attribute { var type = value.GetType(); var name = Enum.GetName(type, value); return type.GetField(name) .GetCustomAttributes(false) .OfType() .SingleOrDefault(); } 

这使得这很容易:

  MultiValueEnum enumVar = MultiValueEnum.First; var enumStringValue = enumVar.GetAttribute().Name; var enumValueDecimal = enumVar.GetAttribute().Percentage; var enumBool = enumVar.GetAttribute().IsGood; 

否则,您可以为枚举创建一个自定义属性,该属性可以保存Guid。

这些线旁边的东西:

 class EnumGuid : Attribute { public Guid Guid; public EnumGuid(string guid) { Guid = new Guid(guid); } } 

然后你就像这样使用它:

 enum Project { [EnumGuid("2ED3164-BB48-499B-86C4-A2B1114BF1")] Cleanup = 1, [EnumGuid("39D31D4-28EC-4832-827B-A11129EB2")] Maintenance = 2 // and so forth, notice the integer value isn't supposed to be used, // it's merely there because not assigning any value is a performance overhead. } 

最后你可以(我总是这样做)创建一个扩展来轻松获取guid:

 static Guid GetEnumGuid(this Enum e) { Type type = e.GetType(); MemberInfo[] memInfo = type.GetMember(e.ToString()); if (memInfo != null && memInfo.Length > 0) { object[] attrs = memInfo[0].GetCustomAttributes(typeof(EnumGuid),false); if (attrs != null && attrs.Length > 0) return ((EnumGuid)attrs[0]).Guid; } throw new ArgumentException("Enum " + e.ToString() + " has no EnumGuid defined!"); } 

所以最后你所需要的只是:

 Guid guid = Project.Cleanup.GetEnumGuid(); 

我使用这种方法将描述附加到枚举,通常是包含空格的较长字符串,因此不能用作名称。

我见过SubSonic用来存储Column和Table名称的这个方法(struct)。

 internal struct Project { public static Guid Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"); public static Guid Maintenance = new Guid("39D31D4-28EC-4832-827B-A129EB2"); public static Guid Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"); public static Guid Sales = new Guid("A5690E7-1111-4AFB-B44D-1DF3AD66D435"); public static Guid Replacement = new Guid("11E5CBA2-EDDE-4ECA-BD63-B725C8C"); public static Guid Modem = new Guid("6F686C73-504B-111-9A0B-850C26FDB25F"); public static Guid Audit = new Guid("30558C7-66D9-4189-9BD9-2B87D11190"); public static Guid Queries = new Guid("9985242-516A-4151-B7DD-851112F562"); } 

编辑: – 感谢您对代码中的缺陷发表评论。 首先,如果Guid字符串无效,它将编译。 至于不创建访问变量的实例是的,它们需要是公共静态的

我可能会去这个字典路线。 基本上有一个查找表:

 public class GuidMapper { private Dictionary mGuidMap = new Dictionary(); public enum GuidTypes: int { Cleanup, Maintenance, Upgrade, Sales, Replacement, Modem, Audit, Queries } public GuidMapper() { mGuidMap.Add(GuidTypes.Cleanup, new Guid("2ED31640-BB48-499B-86C4-A2B1114BF100")); mGuidMap.Add(GuidTypes.Maintenance, new Guid("39D31D40-28EC-4832-827B-A11129EB2000")); mGuidMap.Add(GuidTypes.Upgrade, new Guid("892F8650-E38D-46D7-809A-49510111C100")); mGuidMap.Add(GuidTypes.Sales, new Guid("A5690E70-1111-4AFB-B44D-1DF3AD66D435")); mGuidMap.Add(GuidTypes.Replacement, new Guid("11E5CBA2-EDDE-4ECA-BDFD-63BDBA725C8C")); mGuidMap.Add(GuidTypes.Modem, new Guid("6F686C73-504B-1110-9A0B-850C26FDB25F")); mGuidMap.Add(GuidTypes.Audit, new Guid("30558C70-66D9-4189-9BD9-2B87D1119000")); mGuidMap.Add(GuidTypes.Queries, new Guid("99852420-516A-4151-B7DD-851112F56200")); } public Guid GetGuid(GuidTypes guidType) { if (mGuidMap.ContainsKey(guidType)) { return mGuidMap[guidType]; } return Guid.Empty; } } 

如果你需要适当的enum语义和类型安全性,那么你可以使用这样的模式。

(如果你需要转换操作符, GetUnderlyingTypeToString等附加内容,你可以进一步GetUnderlyingType 。如果你想重新使用具有不同底层类型的多个enum类的模式,那么你可以将任何公共代码移动到generics中,抽象基类。)

 Project x = Project.Cleanup; Project y = Project.Cleanup; Project z = Project.Maintenance; Console.WriteLine(x == y); // True Console.WriteLine(x == z); // False Console.WriteLine(x.Value); // 47801daa-7437-4bfe-a240-9f7c583018a4 // this line will cause a compiler error Console.WriteLine(x == new Guid("47801daa-7437-4bfe-a240-9f7c583018a4")); // ... public class Project { private Project(Guid v) { Value = v; } public Guid Value { get; private set; } public static readonly Project Cleanup = new Project(new Guid("47801daa-7437-4bfe-a240-9f7c583018a4")); public static readonly Project Maintenence = new Project(new Guid("2548a7f3-7bf4-4533-a6c1-dcbcfcdc26a5")); public static readonly Project Upgrade = new Project(new Guid("ed3c3e73-8e6a-4c09-84ae-7f0876d194aa")); } 

当遇到这种问题时,我使用带有consts的结构作为公共成员:

 public struct FileExtensions { public const string ProcessingExtension = ".lck"; public const string ProcessedExtension = ".xml"; public const string FailedExtension = ".failed"; public const string CsvExtension = ".csv"; } 

您可以创建一个仅包含常量值的静态类。 例如:

 internal static class Project { public static readonly Guid Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"); public static readonly Guid Maintenance = new Guid("39D31D4-28EC-4832-827B-A11129EB2"); public static readonly Guid Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"); } 

这样,该类只是作为容器,并且无法从中创建对象。

在VB中,这将是一个模块:

 Friend Module Project Public Shared ReadOnly Cleanup As Guid = New Guid("2ED3164-BB48-499B-86C4-A2B1114BF1") Public Shared ReadOnly Maintenance As Guid = New Guid("39D31D4-28EC-4832-827B-A11129EB2") Public Shared ReadOnly Upgrade As Guid = New Guid("892F865-E38D-46D7-809A-49510111C1") End Module 

枚举类型只能支持 整数类型 (char除外)作为其值。 但是,您可以使用类似字典的内容来查找值的名称。

 Dictionary lookup = new Dictionary(); lookup["Cleanup"] = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"); lookup["Maintenance"] = new Guid("39D31D4-28EC-4832-827B-A11129EB2"); lookup["Upgrade"] = new Guid("892F865-E38D-46D7-809A-49510111C1"); // etc... 

另一种选择是在静态类中具有一系列只读值。

 public static class Guids { public static readonly Guid Cleanup = new Guid("2ED3164-BB48-499B-86C4-A2B1114BF1"); public static readonly Guid Maintenance = new Guid("39D31D4-28EC-4832-827B-A11129EB2"); public static readonly Guid Upgrade = new Guid("892F865-E38D-46D7-809A-49510111C1"); }