Я программировал на Java некоторое время и только что был брошен на проект, полностью написанный на C #. Я пытаюсь ускорить работу в C # и заметил, что перечисления используются в нескольких местах в моем новом проекте, но на первый взгляд перечисления C # кажутся более простыми, чем реализация Java 1.5+. Может кто-нибудь перечислить различия между C # и Java перечислениями, и как преодолеть различия? (Я не хочу начинать языковую войну пламени, я просто хочу знать, как делать некоторые вещи в C #, которые я делал в Java). Например, может ли кто-нибудь опубликовать аналог C # для известного примера перечисления Planet от 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
Огрский псалом33
источник
источник
Ответы:
Перечисления в CLR просто называются константами. Базовый тип должен быть целочисленным. В Java перечисление больше похоже на именованный экземпляр типа. Этот тип может быть довольно сложным и - как показывает ваш пример - содержать несколько полей разных типов.
Чтобы перенести пример на C #, я бы просто изменил перечисление на неизменяемый класс и выставил статические только для чтения экземпляры этого класса:
источник
В C # вы можете определять методы расширения для перечислений, и это восполняет некоторые из отсутствующих функциональных возможностей.
Вы можете определить
Planet
как enum, а также иметь методы расширения, эквивалентныеsurfaceGravity()
иsurfaceWeight()
.Я использовал пользовательские атрибуты, предложенные Михаилом , но того же можно достичь с помощью словаря.
источник
В C # атрибуты могут использоваться с перечислениями. Хороший пример этого шаблона программирования с подробным описанием здесь (Codeproject)
Изменить: этот вопрос был недавно задан снова и ответил Джон Скит: Что эквивалентно перечислению Java в C #? Частные внутренние классы в C # - почему они не используются чаще?
Изменить 2: увидеть принятый ответ, который расширяет этот подход очень блестящим образом!
источник
Перечисления Java на самом деле являются полными классами, которые могут иметь закрытый конструктор, методы и т. Д., Тогда как перечисления C # просто называются целыми числами. Реализация IMO Java намного лучше.
Эта страница должна помочь вам во время изучения c # из java лагеря. (Ссылка указывает на различия в перечислениях (прокрутка вверх / вниз для других целей)
источник
FOO = 0
которое легче использовать в инструментах ORM (неordinal()
требуется использование, склонное к ошибкам ). Далее C # поддерживает побитовые перечисления, которые часто очень полезны, особенно в сочетании сEntityFramework
. Java должна расширять свои перечисления, чтобы они тоже могли быть связаны с целыми числами. Тогда они будут лучше :)Как то так я думаю
Или объедините константы в
Planet
класс, как указано вышеисточник
Вот еще одна интересная идея, которая обслуживает пользовательское поведение, доступное в Java. Я придумал следующий
Enumeration
базовый класс:Он имеет параметр типа в основном просто для того, чтобы порядковый номер работал правильно для разных производных перечислений.
Operator
Пример Джона Скита из его ответа на другой вопрос (http://stackoverflow.com/questions/1376312/whats-the-equivalent-of-javas-enum-in-c) выше становится:Это дает несколько преимуществ.
string
иint
что делает операторы переключения осуществимымиSystem.Enum
могут быть добавлены в базовый класс Enumeration для обеспечения той же функциональности.источник
мы только что сделали расширение enum для c # https://github.com/simonmau/enum_ext
Это всего лишь реализация для typesafeenum, но она прекрасно работает, поэтому мы создали пакет, которым можно поделиться - развлекайтесь с ним
источник
Перечисление Java является синтаксическим сахаром для представления перечислений в виде ОО. Это абстрактные классы, расширяющие класс Enum в Java, и каждое значение enum похоже на статическую конечную реализацию открытого экземпляра класса enum. Посмотрите на сгенерированные классы, и для перечисления «Foo» с 10 значениями вы увидите сгенерированные классы «Foo $ 1» - «Foo $ 10».
Я не знаю C #, но могу только предположить, что перечисление в этом языке больше похоже на традиционное перечисление в языках стиля C. Однако из быстрого поиска в Google видно, что они могут содержать несколько значений, поэтому они, вероятно, реализованы аналогичным образом, но с гораздо большими ограничениями, чем позволяет компилятор Java.
источник
Перечисления Java позволяют легко преобразовывать типы из имени, используя сгенерированный компилятором метод valueOf, т.е.
Эквивалент необработанного перечисления в C # более многословен:
Однако, если вы идете по маршруту, предложенному Кентом, вы можете легко реализовать
ValueOf
метод в своем классе enum.источник
Я подозреваю, что перечисления в C # являются только внутренними константами CLR, но не настолько знакомы с ними. Я декомпилировал некоторые классы в Java, и я могу сказать, что вы хотите, чтобы Enums были после конвертации.
Ява делает что-то подлое. Он рассматривает класс enum как обычный класс, который, насколько я могу судить, использует множество макросов при обращении к значениям enum. Если у вас есть оператор case в классе Java, который использует перечисления, он заменяет ссылки перечисления на целые числа. Если вам нужно перейти к строке, он создает массив строк, проиндексированных по порядковому номеру, который он использует в каждом классе. Я подозреваю, чтобы сэкономить на боксе.
Если вы загрузите этот декомпилятор, вы увидите, как он создает свой класс и интегрирует его. Скорее увлекательно, если честно. Раньше я не использовал класс enum, потому что думал, что он раздут только для массива констант. Мне нравится это лучше, чем ограниченный способ их использования в C #.
http://members.fortunecity.com/neshkov/dj.html - декомпилятор Java
источник
Перечисление в Java намного сложнее, чем перечисление C #, и, следовательно, более мощно. Поскольку это просто еще один синтаксический сахар времени компиляции, мне интересно, стоило ли включать язык, учитывая его ограниченное использование в реальных приложениях. Иногда сложнее не пускать материал в язык, чем отказаться от давления, чтобы включить незначительную функцию.
источник
источник
Вы также можете использовать служебный класс для каждого типа перечисления, который содержит экземпляр с расширенными данными для каждого значения перечисления.
источник