Je programme en Java depuis un moment et je viens de me lancer sur un projet entièrement écrit en C #. J'essaie de me mettre à niveau en C #, et j'ai remarqué que les énumérations étaient utilisées à plusieurs endroits dans mon nouveau projet, mais à première vue, les énumérations de C # semblent être plus simplistes que l'implémentation Java 1.5+. Quelqu'un peut-il énumérer les différences entre les énumérations C # et Java, et comment surmonter les différences? (Je ne veux pas lancer une guerre des flammes du langage, je veux juste savoir comment faire certaines choses en C # que j'avais l'habitude de faire en Java). Par exemple, quelqu'un pourrait-il publier un équivalent C # du célèbre exemple d'énumération Planet de Sun?
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 ...]
c#
java
enums
language-comparisons
Ogre Psaume33
la source
la source
Réponses:
Les énumérations dans le CLR sont simplement nommées constantes. Le type sous-jacent doit être intégral. En Java, une énumération ressemble plus à une instance nommée d'un type. Ce type peut être assez complexe et - comme le montre votre exemple - contenir plusieurs champs de différents types.
Pour porter l'exemple en C #, je changerais simplement l'énumération en une classe immuable et exposerais des instances statiques en lecture seule de cette classe:
la source
En C #, vous pouvez définir des méthodes d'extension sur les énumérations, ce qui compense certaines des fonctionnalités manquantes.
Vous pouvez définir
Planet
comme une énumération et également avoir des méthodes d'extension équivalentes àsurfaceGravity()
etsurfaceWeight()
.J'ai utilisé des attributs personnalisés comme suggéré par Mikhail , mais la même chose pourrait être obtenue en utilisant un dictionnaire.
la source
En C #, les attributs peuvent être utilisés avec des énumérations. Un bon exemple de ce modèle de programmation avec une description détaillée est ici (Codeproject)
Edit: cette question a été récemment posée à nouveau et répondue par Jon Skeet: Quel est l'équivalent de l'énumération de Java en C #? Classes internes privées en C # - pourquoi ne sont-elles pas utilisées plus souvent?
Edit 2: voyez la réponse acceptée qui prolonge cette approche de manière très brillante!
la source
Les énumérations Java sont en fait des classes complètes qui peuvent avoir un constructeur privé et des méthodes, etc., tandis que les énumérations C # ne sont que des entiers nommés. L'implémentation de IMO Java est de loin supérieure.
Cette page devrait vous aider beaucoup tout en apprenant le c # provenant d'un camp java. (Le lien pointe vers les différences concernant les énumérations (faites défiler vers le haut / bas pour d'autres choses)
la source
FOO = 0
qui est plus facile à utiliser dans les outils ORM (aucuneordinal()
utilisation sujette aux erreurs n'est nécessaire). De plus, C # prend en charge les énumérations au niveau du bit qui sont souvent très utiles, en particulier en combinaison avecEntityFramework
. Java devrait étendre leurs énumérations pour leur permettre d'être également liés à des entiers. Alors ils seraient supérieurs :)Quelque chose comme ça je pense:
Ou combinez les constantes dans la
Planet
classe comme ci-dessusla source
Voici une autre idée intéressante qui répond au comportement personnalisé disponible en Java. J'ai proposé la
Enumeration
classe de base suivante :Il a un paramètre de type simplement pour que le nombre ordinal fonctionne correctement dans différentes énumérations dérivées. L'
Operator
exemple de Jon Skeet tiré de sa réponse à une autre question (http://stackoverflow.com/questions/1376312/whats-the-equivalent-of-javas-enum-in-c) ci-dessus devient alors:Cela donne quelques avantages.
string
etint
qui rend les instructions switch faisablesSystem.Enum
peuvent être ajoutées à la classe Enumeration de base pour permettre la même fonctionnalité.la source
nous venons de faire une extension enum pour c # https://github.com/simonmau/enum_ext
C'est juste une implémentation pour le typesafeenum, mais cela fonctionne très bien, nous avons donc créé un package à partager - amusez-vous avec
la source
Une énumération Java est un sucre syntaxique permettant de présenter des énumérations de manière OO. Ce sont des classes abstraites étendant la classe Enum en Java, et chaque valeur enum est comme une implémentation d'instance publique finale statique de la classe enum. Regardez les classes générées, et pour une énumération "Foo" avec 10 valeurs, vous verrez "Foo $ 1" à "Foo $ 10" classes générées.
Cependant, je ne connais pas C #, je ne peux que spéculer qu'une énumération dans ce langage ressemble plus à une énumération traditionnelle dans les langages de style C. Je vois à partir d'une recherche rapide sur Google qu'ils peuvent contenir plusieurs valeurs, ils sont donc probablement implémentés de la même manière, mais avec beaucoup plus de restrictions que ce que le compilateur Java permet.
la source
Les énumérations Java permettent des conversions de type sécurisées faciles à partir du nom en utilisant la méthode valueOf générée par le compilateur, ie
L'équivalent d'une énumération brute en C # est plus détaillé:
Cependant, si vous suivez la route suggérée par Kent, vous pouvez facilement implémenter une
ValueOf
méthode dans votre classe enum.la source
Je soupçonne que les énumérations en C # ne sont que des constantes internes au CLR, mais pas très familières avec elles. J'ai décompilé certaines classes en Java et je peux dire que vous voulez que les Enums soient une fois convertis.
Java fait quelque chose de sournois. Il traite la classe enum comme une classe normale avec, aussi proche que possible, en utilisant de nombreuses macros lors du référencement des valeurs enum. Si vous avez une instruction case dans une classe Java qui utilise des énumérations, elle remplace les références enum aux entiers. Si vous avez besoin d'accéder à string, il crée un tableau de chaînes indexées par un ordinal qu'il utilise dans chaque classe. Je soupçonne d'économiser sur la boxe.
Si vous téléchargez ce décompilateur, vous verrez comment il crée sa classe et l'intègre. Plutôt fascinant pour être honnête. J'avais l'habitude de ne pas utiliser la classe enum parce que je pensais que c'était trop gonflé pour juste un tableau de constantes. Je l'aime mieux que la manière limitée dont vous pouvez les utiliser en C #.
http://members.fortunecity.com/neshkov/dj.html - décompilateur Java
la source
L'énumération en Java est beaucoup plus complexe que l'énumération C # et donc plus puissante. Puisqu'il s'agit simplement d'un autre sucre syntaxique au moment de la compilation, je me demande s'il valait vraiment la peine d'inclure le langage étant donné son utilisation limitée dans les applications réelles. Parfois, il est plus difficile de garder des choses hors de la langue que de céder à la pression d'inclure une fonctionnalité mineure.
la source
la source
Vous pouvez également utiliser une classe utilitaire pour chaque type d'énumération qui contient une instance avec des données avancées pour chaque valeur d'énumération.
la source