在C#中,Java的枚举相当于什么?

Nos*_*ama 27 c# java enums

在C#中,Java的枚举相当于什么?

Jon*_*eet 36

C#中没有完整的Java枚举功能.您可以使用嵌套类型和私有构造函数来合理地关闭.例如:

using System;
using System.Collections.Generic;
using System.Xml.Linq;

public abstract class Operator
{
    public static readonly Operator Plus = new PlusOperator();
    public static readonly Operator Minus = 
         new GenericOperator((x, y) => x - y);
    public static readonly Operator Times = 
         new GenericOperator((x, y) => x * y);
    public static readonly Operator Divide = 
         new GenericOperator((x, y) => x / y);

    // Prevent other top-level types from instantiating
    private Operator()
    {
    }

    public abstract int Execute(int left, int right);

    private class PlusOperator : Operator
    {
        public override int Execute(int left, int right)
        {
            return left + right;
        }
    }

    private class GenericOperator : Operator
    {
        private readonly Func<int, int, int> op;

        internal GenericOperator(Func<int, int, int> op)
        {
            this.op = op;
        }

        public override int Execute(int left, int right)
        {
            return op(left, right);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,你不具备使用嵌套类型,但他们给了方便的"自定义的行为"其中一部分的Java枚举是好的.在其他情况下,您只需将参数传递给私有构造函数即可获得一组众所周知的受限值.

这件事没有给你一些:

  • 顺序支持
  • 切换支持
  • EnumSet
  • 序列化/反序列化(作为单例)

其中一些可能是通过足够的努力来完成的,但如果没有hackery,切换就不可行.现在,如果语言没有这样的事情,它可以通过使两轮牛车自动(如宣称的负荷做一些有趣的事情,使开关工作const自动领域,并改变了枚举类型的任何开关在整数一个开关,只允许"已知"案件.)

哦,部分类型意味着您不必在同一个文件中包含所有枚举值.如果每个值都相关(绝对可能),则每个值都可以拥有自己的文件.

  • @LimitedAtonement:您如何表示案例表达式所需的*常量*值? (2认同)

Chi*_*Chi 18

枚举是少数语言功能之一,在java中比c#更好地实现.在java中,枚举是完全成熟的类型的命名实例,而c#枚举基本上是命名常量.

话虽如此,对于基本情况,它们看起来很相似.但是在java中,你有更强大的功能,因为你可以为各个枚举添加行为,因为它们是完整的类.

你正在寻找一些特别的功能吗?

  • "它们将工作相同" - 而不是IMO,因为常量数字不能具有自定义*行为*,与Java枚举值不同. (8认同)
  • 是的,因此"基本使用"的资格.我同意java enums的一个好处是自定义行为 (2认同)
  • 与 C# 枚举相比,我更喜欢 Java 枚举。使用 C# 枚举,您会传播大量 Switch 语句的味道,并且分散在 switch 语句中的许多代码可以作为与每个枚举关联的方法放置。 (2认同)

And*_*per 6

这是另一个有趣的想法.我提出了以下Enumeration基类:

public abstract class Enumeration<T>
    where T : Enumeration<T>
{   
    protected static int nextOrdinal = 0;

    protected static readonly Dictionary<int, Enumeration<T>> byOrdinal = new Dictionary<int, Enumeration<T>>();
    protected static readonly Dictionary<string, Enumeration<T>> byName = new Dictionary<string, Enumeration<T>>();

    protected readonly string name;
    protected readonly int ordinal;

    protected Enumeration(string name)
        : this (name, nextOrdinal)
    {
    }

    protected Enumeration(string name, int ordinal)
    {
        this.name = name;
        this.ordinal = ordinal;
        nextOrdinal = ordinal + 1;
        byOrdinal.Add(ordinal, this);
        byName.Add(name, this);
    }

    public override string ToString()
    {
        return name;
    }

    public string Name 
    {
        get { return name; }
    }

    public static explicit operator int(Enumeration<T> obj)
    {
        return obj.ordinal;
    }

    public int Ordinal
    {
        get { return ordinal; }
    }
}
Run Code Online (Sandbox Code Playgroud)

它基本上只有一个类型参数,所以序数可以在不同的派生枚举中正常工作.Jon的Operator上述例子变为:

public class Operator : Enumeration<Operator>
{
    public static readonly Operator Plus = new Operator("Plus", (x, y) => x + y);
    public static readonly Operator Minus =  new Operator("Minus", (x, y) => x - y);
    public static readonly Operator Times =  new Operator("Times", (x, y) => x * y);
    public static readonly Operator Divide = new Operator("Divide", (x, y) => x / y);

    private readonly Func<int, int, int> op;

    // Prevent other top-level types from instantiating
    private Operator(string name, Func<int, int, int> op)
        :base (name)
    {
        this.op = op;
    }

    public int Execute(int left, int right)
    {
        return op(left, right);
    }
}
Run Code Online (Sandbox Code Playgroud)

这提供了一些优点.

  • 顺序支持
  • 转换到stringint这使得开关语句可行
  • GetType()将为派生的Enumeration类型的每个值提供相同的结果.
  • 可以将Static方法System.Enum添加到基本Enumeration类中以允许相同的功能.


Bil*_*l K 5

在获得真实的类型安全枚举模式之前,您可能会使用Java中使用的旧的类型安全枚举模式(假设C#中的那些实际上不是注释所声明的类)。该模式仅在本页面中间描述