C#対Java Enum(C#の初心者向け)


182

私はしばらくJavaでプログラミングしていて、完全にC#で書かれたプロジェクトに取り掛かりました。私はC#で速度を上げようとしていますが、新しいプロジェクトのいくつかの場所で列挙型が使用されていることに気付きましたが、一見すると、C#の列挙型はJava 1.5+実装よりも単純に見えます。C#とJavaの列挙型の違いを列挙して、その違いを克服する方法を教えてください。(私は言語の炎上戦争を開始したくありません。Javaで以前使用していたC#でいくつかのことを行う方法を知りたいだけです)。たとえば、誰かがSunの有名なPlanet列挙型の例に対応するC#を投稿できますか?

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
Ogre Psalm33

回答:


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の列挙型は、特にswitchステートメントで使用できるため、おそらくJava 5+の最高の機能です。
MetroidFan2002、2009年

9
@Chris:フラグ列挙型のみを複数形にする必要があります。つまり、メンバーが|を使用して結合される列挙 オペレーター。
ケントブーガート2009

5
@Mladen:それは完全にコンテキストに依存します。惑星の列挙は、限られた数の惑星へのアクセスを提供するゲームに完全に適している場合があります。新しい惑星がゲームに追加された場合、コードの変更はまさにあなたが望むものかもしれません。
ケントブーガート2009

3
@Richie_Wは、Valuesプロパティを使用して列挙型を反復できます。
ジョナサン

23
うわー... JavaよりもC#でより詳細な方法で実装されたものを目にするのはほとんど信じられないことです
Sune Rasmussen 2012

218

C#では拡張メソッドを定義できますでは、列挙型でをこれにより、不足している機能の一部が補われます。

あなたは定義することができますPlanet列挙型としてもと同等の拡張メソッドを持っているsurfaceGravity()surfaceWeight()

私はMikhailによって提案されたカスタム属性を使用しましたが、辞書を使用して同じことを達成できました。

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、2011年

2
絶対そうです。Enumの拡張メソッド(ヘック、拡張メソッド一般)は、C#への優れた追加機能です。
KeithS、2011年

3
@AllonGuralnekありがとう。ただし、メタデータについて誰もが同意するわけではありません。関連するcodereview.stackexchange質問に関する MattDaveyのコメントを参照してください。
finnw

@finnw:私はコードレビューSEサイトを聞いたことがありません-ありがとうございます!私はそこでもこの議論を続けてきました(ただし、ここではプログラマー自身の質問に値するかもしれません)。
Allon Guralnek、2011年

これは素晴らしい解決策です-これのパフォーマンスをテストした人はいますか?たとえば、クラスのプロパティにアクセスする場合と比較して、属性にアクセスするのにかかる時間。
Simon Meyer

35

C#では、属性を列挙型で使用できます。詳細な説明を含むこのプログラミングパターンの良い例はこちら(Codeproject)

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

編集:この質問は最近再び尋ねられ、Jon Skeetが回答しました:C#でのJavaの列挙型に相当するものは何ですか? C#のプライベート内部クラス-なぜ頻繁に使用されないのですか?

編集2:非常に素晴らしい方法でこのアプローチを拡張する受け入れられた答えを見てください!


1
いいね!これは少し不格好に感じますが、それ以外の場合は、列挙型にデータを追加するための非常に許容できる方法です。私は率直に言って、この素晴らしい解決策を説明するのにこれほど長い時間がかかったことに驚いています!
Ogre Psalm33 2009

13

Java列挙型は実際には完全なクラスであり、プライベートコンストラクターやメソッドなどを持つことができますが、C#列挙型は単に整数と呼ばれます。IMO Javaの実装ははるかに優れています。

このページは、JavaキャンプからのC#を学習する際に役立ちます。(リンクは列挙型の違いを示しています(他のものについては上/下にスクロール))


1
あなたのリンクはC#とJavaの類似点と相違点の興味深い広範囲にわたる概要を提供しますが、テキストには多くの誤りがあります(たとえば、Java保護はC#内部と等しいが内部保護されるべきであると誤って述べています)。だから、当たり前のことを当然のことと考えないでください:)
mafu 2009年

1
Javaのファンであっても、Java enumが優れているとは言えません。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
完全ではありません-Planetコンストラクターはプライベートである必要があります。列挙型のポイントの一部は、それらが固定された値のセットであることです。次に、値はPlanetクラスでも定義されます。
Jon Skeet、

未だに。1)列挙子がありません:) 2)列挙型は変更できません。ああ、最後に、コードは1つの単一クラス(プライベートコンストラクターがある場合はesp)を
要求します

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)に対する彼の回答からのJon Skeetの例は、次のようになります。

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これによるswitchステートメントの実現可能性
  • GetType()は、派生した列挙型の各値に対して同じ結果を返します。
  • からの静的メソッドをSystem.Enum同じEnumerationクラスに追加して、同じ機能を実現できます。

3

c#https://github.com/simonmau/enum_extの enum拡張を作成しました

これはタイプセーフの実装にすぎませんが、うまく機能するため、共有するパッケージを作成しました-楽しんでください

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方式で提示するための構文シュガーです。これらはJavaのEnumクラスを拡張する抽象クラスであり、各列挙値は列挙クラスの静的な最終パブリックインスタンス実装のようなものです。生成されたクラスを見てください。値が10の列挙型「Foo」については、生成された「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#のraw enumに相当するものは、より冗長です。

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

ただし、Kentが提案したルートをたどるValueOfと、enumクラスにメソッドを簡単に実装できます。


Javaの例では、コンパイラーによって生成された合成メソッドを使用しています。ジェネリックとはまったく関係ありません。Enumには一般的なvalueOfメソッドがありますが、これはEnumではなくClassのジェネリックを使用します。
トム・ホーティン-09

2

C#の列挙型はCLRの内部の定数にすぎないと思われますが、それらに慣れていません。私はJavaでいくつかのクラスを逆コンパイルしました、そして変換したらEnumが欲しいと言うことができます。

Javaは卑劣なことをします。これは、列挙型クラスを通常のクラスとして扱い、列挙型値を参照するときに多くのマクロを使用して、私が理解できる限り近くにいます。enumを使用するJavaクラスにcaseステートメントがある場合、それは整数へのenum参照を置き換えます。文字列に移動する必要がある場合は、序数によってインデックスが付けられた文字列の配列を作成し、各クラスで使用します。私はボクシングを節約することを疑います。

この逆コンパイラをダウンロードすると、クラスを作成して統合する方法を確認できます。正直に言うと魅力的です。定数の配列だけのために肥大化することだと思ったので、私はenumクラスを使用しませんでした。C#で使用できる制限された方法よりも気に入っています。

http://members.fortunecity.com/neshkov/dj.html-Javaデコンパイラー


0

Javaの列挙型はC#列挙型よりもはるかに複雑であるため、より強力です。これは単なるコンパイル時の構文上の砂糖にすぎないので、実際のアプリケーションでの使用が制限されていることを考えると、その言語を含める価値があったのだろうかと思います。時には、マイナーな機能を含めるようにプレッシャーをあきらめるよりも、言語を回避する方が難しい場合があります。


2
私は敬意を払いません。Java 1.5列挙型は、定数の名前付きアイテムの個別のセットを処理する問題に対して、OO中心のソリューションを実装するために何度も使用した強力な言語機能です。
Ogre Psalm33

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

各列挙値の高度なデータを持つインスタンスを保持する各列挙型のユーティリティクラスを使用することもできます。

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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.