188 votes

C# vs Enum de Java (pour ceux qui découvrent c#)

J'ai été à la programmation en Java pour un certain temps et viens de recevoir jeté sur un projet qui est entièrement écrit en C#. Je suis en train de monter à la vitesse en C#, et a remarqué des enums utilisée dans plusieurs endroits dans mon nouveau projet, mais à première vue, C#'s enums semblent être plus simpliste que le Java 1.5+ mise en œuvre. Quelqu'un peut-il énumérer les différences entre C# et Java enums, et comment surmonter les différences? (Je ne veux pas commencer une langue de flamme de guerre, je veux juste savoir comment faire certaines choses en C# que j'ai utilisé pour faire en Java). Par exemple, quelqu'un pourrait-il poster un C# contrepartie de Soleil célèbres de la Planète enum exemple?

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 ...]

227voto

finnw Points 24592

En C#, vous pouvez définir des méthodes d'extension sur les enums, et de ce fait, certaines des fonctionnalités manquantes.

Vous pouvez définir Planet comme un enum et ont aussi des méthodes d'extension équivalent à surfaceGravity() et surfaceWeight().

J'ai utilisé des attributs personnalisés comme suggéré par Mikhaïl, mais la même chose pourrait être réalisé à l'aide d'un Dictionnaire.

using System;
using System.Reflection;

class PlanetAttr: Attribute
{
    internal PlanetAttr(double mass, double radius)
    {
        this.Mass = mass;
        this.Radius = radius;
    }
    public double Mass { get; private set; }
    public double Radius { get; private set; }
}

public static class Planets
{
    public static double GetSurfaceGravity(this Planet p)
    {
        PlanetAttr attr = GetAttr(p);
        return G * attr.Mass / (attr.Radius * attr.Radius);
    }

    public static double GetSurfaceWeight(this Planet p, double otherMass)
    {
        return otherMass * p.GetSurfaceGravity();
    }

    public const double G = 6.67300E-11;

    private static PlanetAttr GetAttr(Planet p)
    {
        return (PlanetAttr)Attribute.GetCustomAttribute(ForValue(p), typeof(PlanetAttr));
    }

    private static MemberInfo ForValue(Planet p)
    {
        return typeof(Planet).GetField(Enum.GetName(typeof(Planet), p));
    }

}

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

218voto

Kent Boogaart Points 97432

Énumérations dans le Common Language Runtime sont simplement des constantes nommées. Le type sous-jacent doit faire partie intégrante. En Java, une énumération ressemble plus à une instance nommée d’un type. Ce type peut être assez complexe et - comme votre exemple montre - contenir plusieurs champs de divers types.

Pour l’exemple c# de port j’ai juste changer l’enum à une classe immuable et exposer Shared readonly des instances de cette classe :

38voto

Mikhail Points 3393

En C# attributs peuvent être utilisés avec des enums. Bon exemple de programmation de modèle avec la description détaillée est ici (Codeproject)

public enum Planet
{
   [PlanetAttr(3.303e+23, 2.4397e6)]
   Mercury,
   [PlanetAttr(4.869e+24, 6.0518e6)]
   Venus
} 

Edit: cette question a été récemment posée à nouveau et répondit Jon Skeet: Ce qui est l'équivalent de Java enum en C#? Intérieure privée les classes en C# - pourquoi ne sont-ils pas utilisés le plus souvent?

Edit 2: voir la accepté de répondre qui s'étend cette approche dans un très brillant!

13voto

Richard Walton Points 3053

Énumérations Java sont classes réellement complet qui peuvent avoir un constructeur privé et méthodes etc., tandis que c# enums sont nommés tout entiers. Mise en œuvre de l’OMI Java est de loin supérieure.

Cette page devrait vous aider beaucoup tout en apprenant venant d’un camp de java c#. (Le lien pointe vers les différences sur les enums (défilement haut / bas pour d’autres choses)

2voto

JeeBee Points 11882

Un enum de Java est sucre syntaxique pour présenter les énumérations dans un OO. Ils sont des classes abstraites extension de la Enum class en Java, et chaque valeur d'enum, c'est comme un static final de l'instance publique de la mise en œuvre d'enum classe. Regardez les classes générées, et pour un enum "Foo" avec 10 valeurs, vous verrez "Foo$1" par "Foo$10" classes générées.

Je ne sais pas C#, cependant, je ne peux que spéculer qu'un enum dans cette langue est plus traditionnel, enum en C style de langues. Je vois de une rapide recherche sur Google qu'ils peuvent contenir plusieurs valeurs cependant, ils sont probablement mises en œuvre de manière similaire, mais avec beaucoup plus de restrictions que ce que le compilateur Java permet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X