java enums vs C#enums - 缺少功能

Bic*_*ick 10 c# java enums

在java中,我可以轻松地描述带有aditional数据的枚举.
我可以形容这样的事情

public enum OperatorType
{
    GreaterOrEqual  (">=", "GreaterOrEqual"),
    Greater         (">" ,"Greater"),
    Less            ("<", "Less"),
    LessOrEqual     ("<=", "LessOrEqual"),
    Equal           ("==", "Equal"),
    Between         ("Between", "Between"),
    Around          ("Around","Around");

    private final String symbol;
    private final String name;

    private OperatorType(final String symbol, final String name) {
        this.symbol = symbol;
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后添加一个迭代values()的静态方法,将所有数据添加到hashmap中,并允许通过其中一个属性从映射中检索完整枚举数据作为键.

简而言之,enum是java中非常发达的类型.

现在,
转到c#,我的选择是什么?
我想要保存带有属性的枚举,将其加载到地图中,并在需要时按键进行检索.我有什么需要帮助的吗(比如每个枚举的单音 - 这不是一个好主意).
谢谢.

Chr*_*air 9

我只想创建一个类public static readonly,每个类型的实例和沟渠枚举.您可以将它们用作字典键或做任何您喜欢的事情.如果您仍打算将它们映射到基础数据类型(int),那么您也可以为它创建隐式运算符.

public class OperatorType
{
    private static readonly Dictionary<int, OperatorType> OperatorMapping = new Dictionary<int, OperatorType>();

    public static readonly OperatorType GreaterOrEqual  = new OperatorType(0, ">=", "GreaterOrEqual");
    public static readonly OperatorType Greater         = new OperatorType(1, ">", "Greater");



    public readonly String symbol;
    public readonly String name;
    private readonly int underlyingValue;

    private OperatorType(int underlyingValue, string symbol, string name) {
        this.underlyingValue = underlyingValue;
        OperatorMapping[underlyingValue] = this;

        this.symbol = symbol;
        this.name = name;
    }

    public static implicit operator int(OperatorType operatorType)
    {
        return operatorType.underlyingValue;
    }

    public static implicit operator OperatorType(int value)
    {
        return OperatorMapping[value];
    }
}
Run Code Online (Sandbox Code Playgroud)

样品用法:

Dictionary<OperatorType, string> operators = new Dictionary<OperatorType, string>();

operators.Add(OperatorType.GreaterOrEqual, "Greater or equal");

Console.WriteLine(operators[OperatorType.GreaterOrEqual]); //"Greater or equal"

OperatorType operatorType = 1;

Console.WriteLine(operatorType.name); //"Greater"
Run Code Online (Sandbox Code Playgroud)

如果您不关心基础值,请不要包含它.还要考虑Dictionary映射是否应该是线程安全的.您还可以公开静态IEnumerable<OperatorType>(或其他集合)以根据需要定义所有运算符.

编辑:第二个想法,explicit运营商可能更可取代implicit,以符合典型的.NET最佳实践,并更好地匹配典型的enum转换.

  • @Sander:不,在这种情况下,它们被声明为`static readonly` _fields_.这意味着它们在首次访问类型时被分配一次(作为字段初始值设定项,因为我将它写在我的答案中,或者在静态构造函数中)并且在应用程序的生命周期中保持不变.通过使实例构造函数为私有,这意味着`OperatorType`的用户可以_only_使用/引用/访问公开的初始操作符集. (2认同)

Dan*_*den 0

如果您确实需要 C# 中 Java 风格枚举的功能,我看到了三种合理的实现方法:

  1. 使用 C# 枚举和辅助方法的静态类。您会失去类型安全性,但这是一个非常可行的解决方案。

  2. 使用 C# 枚举和一组扩展方法。可能是最惯用的 C# 解决方案,但您仍然必须处理类型安全性的损失(您的扩展方法应该能够处理超出范围的值,即使只是通过抛出异常)。

  3. 使用在 Java 5 中获得关键字之前 Java 中常见的类型安全枚举模式enum。如果每个枚举值都有重要的逻辑,那么这将是我的偏好。