I've been programming in Java for a while and just got thrown onto a project that's written entirely in C#. I'm trying to come up to speed in C#, and noticed enums used in several places in my new project, but at first glance, C#'s enums seem to be more simplistic than the Java 1.5+ implementation. Can anyone enumerate the differences between C# and Java enums, and how to overcome the differences? (I don't want to start a language flame war, I just want to know how to do some things in C# that I used to do in Java). For example, could someone post a C# counterpart to Sun's famous Planet enum example?

public enum Planet {
  MERCURY (3.303e+23, 2.4397e6),
  VENUS   (4.869e+24, 6.0518e6),
  EARTH   (5.976e+24, 6.37814e6),
  MARS    (6.421e+23, 3.3972e6),
  JUPITER (1.9e+27,   7.1492e7),
  SATURN  (5.688e+26, 6.0268e7),
  URANUS  (8.686e+25, 2.5559e7),
  NEPTUNE (1.024e+26, 2.4746e7),
  PLUTO   (1.27e+22,  1.137e6);

  private final double mass;   // in kilograms
  private final double radius; // in meters
  Planet(double mass, double radius) {
      this.mass = mass;
      this.radius = radius;
  }
  public double mass()   { return mass; }
  public double radius() { return radius; }

  // universal gravitational constant  (m3 kg-1 s-2)
  public static final double G = 6.67300E-11;

  public double surfaceGravity() {
      return G * mass / (radius * radius);
  }
  public double surfaceWeight(double otherMass) {
      return otherMass * surfaceGravity();
  }
}

// Example usage (slight modification of Sun's example):
public static void main(String[] args) {
    Planet pEarth = Planet.EARTH;
    double earthRadius = pEarth.radius(); // Just threw it in to show usage

    // Argument passed in is earth Weight.  Calculate weight on each planet:
    double earthWeight = Double.parseDouble(args[0]);
    double mass = earthWeight/pEarth.surfaceGravity();
    for (Planet p : Planet.values())
       System.out.printf("Your weight on %s is %f%n",
                         p, p.surfaceWeight(mass));
}

// Example output:
$ java Planet 175
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
[etc ...]

当前回答

Java枚举是一种语法糖,用于以面向对象的方式表示枚举。它们是在Java中扩展Enum类的抽象类,每个枚举值都类似于枚举类的静态最终公共实例实现。查看生成的类,对于包含10个值的枚举“Foo”,您将看到生成了“Foo$1”到“Foo$10”类。

虽然我不懂c#,但我只能推测,这种语言中的枚举更像C风格语言中的传统枚举。然而,我从一个快速的谷歌搜索中看到,它们可以保存多个值,因此它们可能以类似的方式实现,但限制比Java编译器所允许的要多得多。

其他回答

Java枚举实际上是一个完整的类,可以有一个私有构造函数和方法等,而c#枚举只是命名的整数。IMO Java的实现要优越得多。

当你从java营地学习c#时,这个页面应该会对你有很大的帮助。(该链接指向关于枚举的差异(向上/向下滚动查看其他内容)

我想是这样的:

public class Planets 
{
    public static readonly Planet MERCURY = new Planet(3.303e+23, 2.4397e6);
    public static readonly Planet VENUS = new Planet(4.869e+24, 6.0518e6);
    public static readonly Planet EARTH = new Planet(5.976e+24, 6.37814e6);
    public static readonly Planet MARS = new Planet(6.421e+23, 3.3972e6);
    public static readonly Planet JUPITER = new Planet(1.9e+27,   7.1492e7);
    public static readonly Planet SATURN = new Planet(5.688e+26, 6.0268e7);
    public static readonly Planet URANUS = new Planet(8.686e+25, 2.5559e7);
    public static readonly Planet NEPTUNE = new Planet(1.024e+26, 2.4746e7);
    public static readonly Planet PLUTO = new Planet(1.27e+22,  1.137e6);
}

public class Planet
{
    public double Mass {get;private set;}
    public double Radius {get;private set;}

    Planet(double mass, double radius)
    {
        Mass = mass;
        Radius = radius;
    }

    // universal gravitational constant  (m3 kg-1 s-2)
    private static readonly double G = 6.67300E-11;

    public double SurfaceGravity()
    {
        return G * Mass / (Radius * Radius);
    }

    public double SurfaceWeight(double otherMass)
    {
        return otherMass * SurfaceGravity();
    }
}

或者像上面那样将常量组合到Planet类中

Java枚举是一种语法糖,用于以面向对象的方式表示枚举。它们是在Java中扩展Enum类的抽象类,每个枚举值都类似于枚举类的静态最终公共实例实现。查看生成的类,对于包含10个值的枚举“Foo”,您将看到生成了“Foo$1”到“Foo$10”类。

虽然我不懂c#,但我只能推测,这种语言中的枚举更像C风格语言中的传统枚举。然而,我从一个快速的谷歌搜索中看到,它们可以保存多个值,因此它们可能以类似的方式实现,但限制比Java编译器所允许的要多得多。

我怀疑c#中的枚举只是CLR内部的常量,但不是很熟悉它们。我已经在Java中反编译了一些类,我可以告诉你想要的enum是一旦你转换。

Java做了一些狡猾的事情。它将枚举类视为一个普通类,在引用枚举值时使用大量宏。如果在使用枚举的Java类中有case语句,则它将枚举引用替换为整数。如果需要转到string,它会创建一个字符串数组,由它在每个类中使用的序数索引。我猜是为了节省拳击的费用。

如果你下载了这个反编译器,你会看到它如何创建它的类并集成它。说实话,相当吸引人。我过去不使用枚举类,因为我认为它对于一个常量数组来说太臃肿了。比起在c#中有限的使用方式,我更喜欢它。

http://members.fortunecity.com/neshkov/dj.html——Java反编译器

Java中的枚举比c#中的枚举复杂得多,因此功能更强大。 由于它只是另一种编译时语法糖,我想知道考虑到它在实际应用程序中的有限使用,是否真的值得包含该语言。 有时候,将一些东西排除在语言之外比屈服于包含一个小特性的压力更难。