将附加信息与.NET Enum相关联

我的问题最好用一个例子来说明。

假设我有枚举:

public enum ArrowDirection { North, South, East, West } 

我想将对应于每个方向的单位向量与该方向相关联。 例如,我想要返回(0,1)for North,(-1,0)for West等等。我知道在Java中你可以在枚举中声明一个可以提供该function的方法。

我当前的解决方案是使用静态方法 – 在定义枚举的类中 – 返回与传递的ArrowDirection相对应的向量(该方法使用HashTable来完成查找,但这并不重要)。 这似乎……不洁净。

题:
是否有最佳实践解决方案来存储与.NET中的枚举相对应的附加信息?

在C#3.0中有一种奇妙的新方法。 关键是这个美丽的事实:枚举可以有扩展方法! 所以,这是你可以做的:

 public enum ArrowDirection { North, South, East, West } public static class ArrowDirectionExtensions { public static UnitVector UnitVector(this ArrowDirection self) { // Replace this with a dictionary or whatever you want ... you get the idea switch(self) { case ArrowDirection.North: return new UnitVector(0, 1); case ArrowDirection.South: return new UnitVector(0, -1); case ArrowDirection.East: return new UnitVector(1, 0); case ArrowDirection.West: return new UnitVector(-1, 0); default: return null; } } } 

现在,您可以这样做:

 var unitVector = ArrowDirection.North.UnitVector(); 

甜! 我大约一个月前才发现这个问题,但这是新C#3.0function的一个非常好的结果。

这是我博客上的另一个例子。

我在这里写了博客。

尝试使用Attributes这样的东西。

  public enum Status { [Status(Description = "Not Available")] Not_Available = 1, [Status(Description = "Available For Game")] Available_For_Game = 2, [Status(Description = "Available For Discussion")] Available_For_Discussion = 3, } public class StatusEnumInfo { private static StatusAttribute[] edesc; public static String GetDescription(object e) { System.Reflection.FieldInfo f = e.GetType().GetField(e.ToString()); StatusEnumInfo.edesc = f.GetCustomAttributes(typeof(StatusAttribute), false) as StatusAttribute[]; if (StatusEnumInfo.edesc != null && StatusEnumInfo.edesc.Length == 1) return StatusEnumInfo.edesc[0].Description; else return String.Empty; } public static object GetEnumFromDesc(Type t, string desc) { Array x = Enum.GetValues(t); foreach (object o in x) { if (GetDescription(o).Equals(desc)) { return o; } } return String.Empty; } } public class StatusAttribute : Attribute { public String Description { get; set; } } public class Implemenation { public void Run() { Status statusEnum = (Status)StatusEnumInfo.GetEnumFromDesc(typeof(Status), "Not Available"); String statusString = StatusEnumInfo.GetDescription(Status.Available_For_Discussion); } } 

而不是说明 ,使用您的自定义属性

 using System.ComponentModel; using System.Reflection; public enum ArrowDirection { [Description("Northwards")] North, [Description("Southwards")] South, [Description("Eastwards")] East, [Description("Westwards")] West } 

创建扩展方法以获取描述列表:

 public static class Enum where T : struct { ///  /// Gets a collection of the enum value descriptions. ///  ///  public static IList GetDescriptions() { List descriptions = new List(); foreach (object enumValue in Enum.GetValues()) { descriptions.Add(((Enum)enumValue).ToDescription()); } return descriptions; } } 

你可以看到的一件事是“Type-Safe Enum”模式。 这允许你创建一个实际上是一个完整的静态对象的枚举,它可以有方法/属性/等。

http://www.javacamp.org/designPattern/enum.html

Joshua Bloch在他的“Effective Java”一书中讨论了这种模式。 我已经在很多不同的情况下使用过它,我实际上更喜欢它而不是简单的枚举。 (它与语言无关 – 它适用于Java,C#或几乎任何OO语言)。

你的静态方法对我来说似乎很干净。 您将枚举和静态方法封装在同一个类中。 对枚举的更改集中在该单个类中。

在枚举中添加一个方法(根据Java)似乎增加了一些非常简单的概念。

基于属性的方法很有意思,但与静态方法相比,似乎再次使事情过于复杂。