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

时间:2009-03-25 06:58:33

标签: c# .net enums

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

假设我有枚举:

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

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

我目前的解决方案是使用一个静态方法 - 在定义枚举的类中 - 返回一个对应于传入的ArrowDirection的向量(该方法使用HashTable来完成查找,但这并不重要)。这似乎......不洁净。

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

5 个答案:

答案 0 :(得分:37)

在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.0功能的一个非常好的结果。

Here's another example on my blog.

答案 1 :(得分:3)

我在博客上发表了here

使用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);

    }

  }

使用自定义属性

代替描述

答案 2 :(得分:1)

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<T> where T : struct
{

    /// <summary>
    /// Gets a collection of the enum value descriptions.
    /// </summary>
    /// <returns></returns>
    public static IList<string> GetDescriptions()
    {
        List<string> descriptions = new List<string>();
        foreach (object enumValue in Enum<T>.GetValues())
        {
            descriptions.Add(((Enum)enumValue).ToDescription());
        }
        return descriptions;

    }
}

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

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

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

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