由于枚举使用整数,我可以使用哪种其他结构来对类链接的值进行类似枚举的访问:
[我知道这是错的,正在寻找替代方案]
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<TAttribute>(this Enum value)
where TAttribute : Attribute
{
var type = value.GetType();
var name = Enum.GetName(type, value);
return type.GetField(name)
.GetCustomAttributes(false)
.OfType<TAttribute>()
.SingleOrDefault();
}
这使得这很容易:
MultiValueEnum enumVar = MultiValueEnum.First;
var enumStringValue = enumVar.GetAttribute<FooAttribute>().Name;
var enumValueDecimal = enumVar.GetAttribute<FooAttribute>().Percentage;
var enumBool = enumVar.GetAttribute<FooAttribute>().IsGood;
答案 0 :(得分:25)
否则你可以为你的枚举创建一个自定义属性,它可以保存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();
我使用这种方法将描述附加到枚举,通常是包含空格的较长字符串,因此不能用作名称。
答案 1 :(得分:11)
我见过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字符串无效,它将编译。至于不创建实例来访问变量是的,他们需要公共静态
答案 2 :(得分:5)
我可能会去这个字典路线。基本上有一个查找表:
public class GuidMapper
{
private Dictionary<GuidTypes, Guid> mGuidMap = new Dictionary<GuidTypes, Guid>();
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;
}
}
答案 3 :(得分:2)
如果您需要正确的enum
- 类似语义和类型安全,那么您可以使用这样的模式。
(如果您需要转换操作符,GetUnderlyingType
,ToString
等额外内容,您可以进一步充实它。如果您想重复使用多个enum
的模式 - 类似的类使用不同的底层类型,您可以将任何公共代码移动到通用的抽象基类中。)
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"));
}
答案 4 :(得分:0)
当遇到这种问题时,我使用了具有consts的结构作为公共成员:
public struct FileExtensions
{
public const string ProcessingExtension = ".lck";
public const string ProcessedExtension = ".xml";
public const string FailedExtension = ".failed";
public const string CsvExtension = ".csv";
}
答案 5 :(得分:0)
您可以创建一个仅包含常量值的静态类。 例如:
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
答案 6 :(得分:0)
枚举类型可以only support integral types(除了char)作为其值。但是,您可以使用像Dictionary这样的内容来查找值的名称。
Dictionary<Guid> lookup = new Dictionary<Guid>();
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");
}