C # vs Java Enum (для тих, хто не працює в C #)


182

Я деякий час програмував на Java і просто кинувся на проект, повністю написаний на C #. Я намагаюсь швидко досягти C #, і помітив перерахунки, які використовуються в моєму новому проекті в декількох місцях, але, на перший погляд, перерахунки C # здаються більш спрощеними, ніж реалізація Java 1.5+. Чи може хтось перерахувати відмінності між перерахунками C # та Java, і як подолати різниці? (Я не хочу розпочати війну з мовним полум’ям, я просто хочу знати, як робити деякі речі в C #, що я раніше робив на Java). Наприклад, хтось може опублікувати аналог C # на прикладі відомого Планета Сума від 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 ...]

1
@ycomp Я не можу взяти на це кредит. Він походить від Sun (зараз Oracle): docs.oracle.com/javase/tutorial/java/javaOO/enum.html
Псалм33 Огре

Відповіді:


210

Перерахування в CLR просто називаються константами. Основний тип повинен бути інтегральним. У Java перерахування більше нагадує названий екземпляр типу. Цей тип може бути досить складним і, як показує ваш приклад, містити кілька полів різних типів.

Щоб перенести приклад на C #, я просто змінив перерахунок на незмінний клас і виклав статичні екземпляри, які читаються лише для цього класу:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Planet planetEarth = Planet.MERCURY;

            double earthRadius = pEarth.Radius; // Just threw it in to show usage
            double earthWeight = double.Parse("123");
            double earthMass   = earthWeight / pEarth.SurfaceGravity();

            foreach (Planet p in Planet.Values)
                Console.WriteLine($"Your weight on {p} is {p.SurfaceWeight(mass)}");

            Console.ReadKey();
        }
    }

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

        public static IEnumerable<Planet> Values
        {
            get
            {
                yield return MERCURY;
                yield return VENUS;
                yield return EARTH;
                yield return MARS;
                yield return JUPITER;
                yield return SATURN;
                yield return URANUS;
                yield return NEPTUNE;
                yield return PLUTO;
            }
        }

        public string Name   { get; private set; }
        public double Mass   { get; private set; }
        public double Radius { get; private set; }

        Planet(string name, double mass, double radius) => 
            (Name, Mass, Radius) = (name, mass, radius);

        // Wniversal gravitational constant  (m3 kg-1 s-2)
        public const double G = 6.67300E-11;
        public double SurfaceGravity()            => G * mass / (radius * radius);
        public double SurfaceWeight(double other) => other * SurfaceGravity();
        public override string ToString()         => name;
    }
}

4
Це такий собі безпечний для переліку тип, що нам, бідним людям, змушеним користуватися Java 1.4 і нижче, доводиться реалізовувати ... Перерахунки Java 5 - це, мабуть, найкраща особливість Java 5+, тим більше, що їх можна використовувати в операторах переключення.
MetroidFan2002

9
@Chris: слід лише множини прапорців. Тобто перерахування, члени яких об'єднані за допомогою | оператор.
Кент Бугаарт

5
@Mladen: Це повністю залежить від контексту. Перерахування планет може бути ідеально підходить до гри, яка забезпечує доступ до обмеженої кількості планет. Зміни коду можуть бути саме те, що ви хочете, якщо в гру буде додана нова планета.
Кент Бугаарт

3
@Richie_W ви можете переглядати переліки за допомогою властивості Values.
Джонатан

23
Нічого ... Неймовірно бачити щось більш багатослівне в C #, ніж на Яві
Sune Rasmussen,

218

У C # ви можете визначити методи розширення на enums, і це доповнює деякі недоліки функціоналу.

Ви можете визначити Planetяк enum, а також мати методи розширення, еквівалентні surfaceGravity()та surfaceWeight().

Я використовував власні атрибути, як запропонував Михайло , але те саме можна досягти за допомогою Словника.

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
}

20
Я думаю, що за це слід проголосувати більше. Це ближче до того, як працюють ентузіасти на Java. Я можу зробити щось на кшталт Planet.MERCURY.GetSurfaceGravity () <- Зверніть увагу на метод розширення на Enum!
thenonhacker

2
Однозначно так. Методи розширення на Enums (хек, методи розширення взагалі) - чудове доповнення до C #.
KeithS

3
@AllonGuralnek Дякую Однак не всі погоджуються щодо метаданих. Дивіться коментар MattDavey щодо пов'язаного питання codereview.stackexchange .
finnw

@finnw: Я ніколи не чув про сайт Code Review SE - дякую за це! Я продовжую цю дискусію там (хоча це, можливо, заслуговує на власне запитання тут про програмістів).
Аллон Гуралнек

це чудове рішення - хтось перевіряв ефективність цього? наприклад, скільки часу займає доступ до атрибута ta порівняно з доступом до властивості класу.
Саймон Мейєр

35

У C # атрибути можуть використовуватися із перерахунками. Хороший приклад цієї схеми програмування з детальним описом є тут (Codeproject)

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

Редагувати: це питання нещодавно знову задали і відповів Джон Скіт: Який еквівалент перерахунку Java в C #? Приватні внутрішні класи в C # - чому їх не використовують частіше?

Редагуйте 2: подивіться прийняту відповідь, яка надзвичайно блискуче розширює цей підхід!


1
Приємно! Це відчувається лише трохи незграбно, але в іншому випадку є дуже прийнятним методом додавання додаткових даних до перерахунків. Я відверто вражений, що комусь так довго потрібно було згадати про це чудове рішення!
Огрійський псалом33

13

Перерахунки Java - це фактично повні класи, які можуть мати приватний конструктор та методи тощо, тоді як C # перерахунки просто називають цілими числами. Реалізація IMO Java значно краща.

Ця сторінка повинна вам дуже допомогти при навчанні c #, що надходить з табору java. (Посилання вказує на відмінності щодо перерахунків (прокручування вгору / вниз для інших речей)


1
Хоча ваше посилання дає цікавий, обширний огляд схожості та відмінностей між C # та Java, в тексті є багато помилок (наприклад, неправильно зазначено, що захищена Java дорівнює C # внутрішній, тоді як вона повинна бути захищеною внутрішньою). Тому не сприймайте все як належне :)
mafu

1
Я б не сказав, що енуми Java переважають, навіть якщо я фанат Java. C # підтримує просте декларування цілих чисел, таке, FOO = 0яке простіше використовувати в інструментах ORM ( ordinal()використання схильних до помилок не потрібно). Далі C # підтримує побітові перерахування, які часто дуже корисні, особливо в поєднанні з EntityFramework. Java повинна розширити свої перерахунки, щоб вони також могли бути прив'язані до цілих чисел. Тоді вони були б вищі :)
djmj

4

Щось таке я думаю:

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клас, як зазначено вище


8
Не зовсім - конструктор Планети повинен бути приватним; частина точки перерахунків полягає в тому, що вони є фіксованим набором значень. Значення будуть визначені і в класі Планети.
Джон Скіт

Ще ні. 1) нумератор відсутній :) 2) перерахунки ніколи не повинні змінюватися. Ну і останнє, ваш код просить одного класу (особливо, коли у вас є приватний конструктор)
nawfal

3

Ось ще одна цікава ідея, яка обслуговує власну поведінку, наявну на Java. Я придумав наступний 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; }
    }
}

Він має параметр типу в основному просто так, щоб порядковий підрахунок буде працювати належним чином у різних похідних перерахуваннях. Джон СкітOperatorПриклад з його відповіді на інше питання (http://stackoverflow.com/questions/1376312/whats-the-equivalent-of-javas-enum-in-c) вище:

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);
    }
}

Це дає кілька переваг.

  • Звичайна підтримка
  • Перетворення на stringтаint робить оператори переключення можливими
  • GetType () дасть однаковий результат для кожного зі значень похідного типу Перерахування.
  • Статичні методи з System.Enumможна додати до базового класу перерахування, щоб дозволити однакову функціональність.

3

ми щойно зробили розширення enum для c # https://github.com/simonmau/enum_ext

Це просто реалізація для typesafeenum, але вона чудово працює, тому ми зробили пакет для спільного використання - розважимось

public sealed class Weekday : TypeSafeNameEnum<Weekday, int>
{
    public static readonly Weekday Monday = new Weekday(1, "--Monday--");
    public static readonly Weekday Tuesday = new Weekday(2, "--Tuesday--");
    public static readonly Weekday Wednesday = new Weekday(3, "--Wednesday--");
    ....

    private Weekday(int id, string name) : base(id, name)
    {
    }
}

2

Перерахунок Java - це синтаксичний цукор для подання перерахувань у вигляді OO. Вони абстрактні класи, що розширюють клас Enum в Java, і кожне значення enum є як статична остаточна реалізація загальнодоступним екземпляром класу enum. Подивіться на згенеровані класи, і для перерахунку "Foo" з 10 значеннями ви побачите "Foo $ 1" через "Foo $ 10" створені класи.

Я не знаю C #, проте я можу лише припускати, що перерахунок на цій мові більше схожий на традиційний перелік мов стилю C. З швидкого пошуку в Google я бачу, що вони можуть містити кілька значень, тому вони, ймовірно, реалізуються аналогічно, але з набагато більшими обмеженнями, ніж те, що дозволяє компілятор Java.


3
Чи не все в Java та C # все стосується синтаксичного цукру для байткодів JVM чи CLR? :) Просто кажу
thenonhacker

2

Перерахунки Java дозволяють легко перетворити напевне безпечне перетворення з імені за допомогою методу valueOf, створеного компілятором, тобто

// Java Enum has generics smarts and allows this
Planet p = Planet.valueOf("MERCURY");

Еквівалент для сирого перерахунку в C # є більш багатослівним:

// C# enum - bit of hoop jumping required
Planet p = (Planet)Enum.Parse(typeof(Planet), "MERCURY");

Однак, якщо ви спускаєтесь по маршруту, підданому Kent, ви можете легко реалізувати ValueOfметод у вашому класі перерахунку.


У прикладі Java використовується синтетичний метод, сформований компілятором - взагалі нічого спільного з генерікою. У Enum є загальний метод valueOf, але він використовує дженерики класу, а не Enum.
Том Хоутін - тайклін

2

Я підозрюю, що перерахунки в C # є просто константами, що знаходяться в CLR, але не з ними знайомі. Я декомпілював декілька класів на Java, і можу сказати, що ви хочете, щоб Enums колись здійснив конвертацію.

Java робить щось підступне. Він розглядає клас enum як звичайний клас із, максимально близьким, як я можу зрозуміти, використовуючи безліч макросів при посиланні на значення enum. Якщо у вас є випадок регістру в класі Java, який використовує enums, він замінює посилання enum на цілі числа. Якщо вам потрібно перейти до рядка, він створює масив рядків, індексованих порядковим кодом, який він використовує у кожному класі. Підозрюю, що економити на боксі.

Якщо ви завантажите цей декомпілятор, ви побачите, як він створює свій клас і інтегрує його. Досить захоплююче, якщо чесно. Раніше я не використовував клас enum, тому що думав, що він роздутий лише для масиву констант. Мені це подобається краще, ніж обмежений спосіб їх використання в C #.

http://members.fortunecity.com/neshkov/dj.html - декомпілятор Java


0

Перерахунок на Java набагато складніший за перелік C # і, отже, потужніший. Оскільки це лише черговий синтаксичний цукор часу компіляції, мені цікаво, чи дійсно варто було включити мову з огляду на її обмежене використання в реальному житті. Іноді складніше зберігати речі з мови, ніж відмовлятися від тиску, щоб включити незначну функцію.


2
Я з повагою не згоден. Перерахунки Java 1.5 - це потужна мовна функція, яку я неодноразово використовував, щоб реалізувати більш орієнтоване на OO вирішення проблеми, що стосується дискретного набору постійних названих елементів.
Огрійський псалом33,

1
Можливо, ти це зробив. Але крім інтелектуальної інтеграції мови «перемикання», решту функціональних можливостей можна легко відтворити на C # або саму Java, як показано вище.
dmihailescu

@dmihailescu "Тоді перерахування на Java набагато складніше, ніж C #. Тому я кинув Java ..."
Mukus

0
//Review the sample enum below for a template on how to implement a JavaEnum.
//There is also an EnumSet implementation below.

public abstract class JavaEnum : IComparable {
    public static IEnumerable<JavaEnum> Values {
        get {
            throw new NotImplementedException("Enumeration missing");
        }
    }

    public readonly string Name;

    public JavaEnum(string name) {
        this.Name = name;
    }

    public override string ToString() {
        return base.ToString() + "." + Name.ToUpper();
    }

    public int CompareTo(object obj) {
        if(obj is JavaEnum) {
            return string.Compare(this.Name, ((JavaEnum)obj).Name);
        } else {
            throw new ArgumentException();
        }
    }


    //Dictionary values are of type SortedSet<T>
    private static Dictionary<Type, object> enumDictionary;
    public static SortedSet<T> RetrieveEnumValues<T>() where T : JavaEnum {
        if(enumDictionary == null) {
            enumDictionary = new Dictionary<Type, object>();
        }
        object enums;
        if(!enumDictionary.TryGetValue(typeof(T), out enums)) {
            enums = new SortedSet<T>();
            FieldInfo[] myFieldInfo = typeof(T).GetFields(BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public);
            foreach(FieldInfo f in myFieldInfo) {
                if(f.FieldType == typeof(T)) {
                    ((SortedSet<T>)enums).Add((T)f.GetValue(null));
                }
            }
            enumDictionary.Add(typeof(T), enums);
        }
        return (SortedSet<T>)enums;
    }
}


//Sample JavaEnum
public class SampleEnum : JavaEnum {
    //Enum values
    public static readonly SampleEnum A = new SampleEnum("A", 1);
    public static readonly SampleEnum B = new SampleEnum("B", 2);
    public static readonly SampleEnum C = new SampleEnum("C", 3);

    //Variables or Properties common to all enums of this type
    public int int1;
    public static int int2 = 4;
    public static readonly int int3 = 9;

    //The Values property must be replaced with a call to JavaEnum.generateEnumValues<MyEnumType>() to generate an IEnumerable set.
    public static new IEnumerable<SampleEnum> Values {
        get {
            foreach(var e in JavaEnum.RetrieveEnumValues<SampleEnum>()) {
                yield return e;
            }
            //If this enum should compose several enums, add them here
            //foreach(var e in ChildSampleEnum.Values) {
            //    yield return e;
            //}
        }
    }

    public SampleEnum(string name, int int1)
        : base(name) {
        this.int1 = int1;
    }
}


public class EnumSet<T> : SortedSet<T> where T : JavaEnum {
    // Creates an enum set containing all of the elements in the specified element type.
    public static EnumSet<T> AllOf(IEnumerable<T> values) {
        EnumSet<T> returnSet = new EnumSet<T>();
        foreach(T item in values) {
            returnSet.Add(item);
        }
        return returnSet;
    }

    // Creates an enum set with the same element type as the specified enum set, initially containing all the elements of this type that are not contained in the specified set.
    public static EnumSet<T> ComplementOf(IEnumerable<T> values, EnumSet<T> set) {
        EnumSet<T> returnSet = new EnumSet<T>();
        foreach(T item in values) {
            if(!set.Contains(item)) {
                returnSet.Add(item);
            }
        }
        return returnSet;
    }

    // Creates an enum set initially containing all of the elements in the range defined by the two specified endpoints.
    public static EnumSet<T> Range(IEnumerable<T> values, T from, T to) {
        EnumSet<T> returnSet = new EnumSet<T>();
        if(from == to) {
            returnSet.Add(from);
            return returnSet;
        }
        bool isFrom = false;
        foreach(T item in values) {
            if(isFrom) {
                returnSet.Add(item);
                if(item == to) {
                    return returnSet;
                }
            } else if(item == from) {
                isFrom = true;
                returnSet.Add(item);
            }
        }
        throw new ArgumentException();
    }

    // Creates an enum set initially containing the specified element(s).
    public static EnumSet<T> Of(params T[] setItems) {
        EnumSet<T> returnSet = new EnumSet<T>();
        foreach(T item in setItems) {
            returnSet.Add(item);
        }
        return returnSet;
    }

    // Creates an empty enum set with the specified element type.
    public static EnumSet<T> NoneOf() {
        return new EnumSet<T>();
    }

    // Returns a copy of the set passed in.
    public static EnumSet<T> CopyOf(EnumSet<T> set) {
        EnumSet<T> returnSet = new EnumSet<T>();
        returnSet.Add(set);
        return returnSet;
    }

    // Adds a set to an existing set.
    public void Add(EnumSet<T> enumSet) {
        foreach(T item in enumSet) {
            this.Add(item);
        }
    }

    // Removes a set from an existing set.
    public void Remove(EnumSet<T> enumSet) {
        foreach(T item in enumSet) {
            this.Remove(item);
        }
    }
}

0

Ви також можете використовувати клас утиліти для кожного типу enum, який містить примірник із розширеними даними для кожного значення enum.

public enum Planet
{
    MERCURY,
    VENUS
}

public class PlanetUtil
{
    private static readonly IDictionary<Planet, PlanetUtil> PLANETS = new Dictionary<Planet, PlanetUtil();

    static PlanetUtil()
    {
        PlanetUtil.PLANETS.Add(Planet.MERCURY, new PlanetUtil(3.303e+23, 2.4397e6));
        PlanetUtil.PLANETS.Add(Planet.VENUS, new PlanetUtil(4.869e+24, 6.0518e6));
    }

    public static PlanetUtil GetUtil(Planet planet)
    {
        return PlanetUtil.PLANETS[planet];
    }

    private readonly double radius;
    private readonly double mass;

    public PlanetUtil(double radius, double mass)
    {
        this.radius = radius;
        this.mass = mass;
    }

    // getter
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.