列挙型と定数。いつ使用するのですか?


94

私は列挙型をいくつか読んでいて、定数の宣言と非常に似ていることがわかりました。列挙型ではなく定数を使用する場合、またはその逆の場合はどうすればわかりますか?列挙型を使用する利点は何ですか?



Javaの同様の質問については、stackoverflow.com / questions / 11575376 /…も参照してください(回答は主にC#にも適用されます)。
Alexei Levenkov

回答:


95

何かが取り得る値の範囲を定義したい場合は、列挙型を使用してください。色は次のような明白な例です。

public enum Colour
{
    White,
    Red,
    Blue
}

または、おそらく次のような可能性のあるもののセット:(私は怠惰なので、ここから盗んだ例)

[FlagsAttribute]
enum DistributedChannel
{
  None = 0,
  Transacted = 1,
  Queued = 2,
  Encrypted = 4,
  Persisted = 16,
  FaultTolerant = Transacted | Queued | Persisted
}

定数は、PIのように単一の値にする必要があります。PI値の範囲はなく、PIのみがあります。

考慮すべきその他のポイントは次のとおりです。

  • a:定数は必ずしも定数間の関係を示すものではありませんが、列挙型は何かが列挙型によって定義されたセットの1つである可能性があることを示します。
  • b:定義された列挙型を引数として使用すると、型チェックに役立ちます。定数は単なる値であるため、追加のセマンティック情報は提供されません。

1
あなたは何を使用して終了場合.ToString()のconst文字列とそのルックスをクラスを使用するには、列挙型の上に任意の値を多くのことをして列挙が、回避への呼び出しのような役割を果たしToString()
シンジャイ

待って、私は自分の質問に答えたと思います。この例のコードは機能しません。入力を文字列として受け取る必要があるため、実際には列挙型のようには動作しません。
シンジャイ

1
なぜ列挙型ではなく定数色の静的クラスColorだけができないのですか?違いは何ですか?
WDUK 2018年

短い声明Type Safety"
ahmednabil88

30

他の答えに欠けているのは、列挙型が整数の基本型を持っているということです。次のように、デフォルトをintからchar以外の整数型に変更できます。

enum LongEnum : long {
    foo,
    bar,
}

基本タイプから明示的および暗黙的にキャストできます。これは、スイッチステートメントで役立ちます。enumに適切な値を持つメンバーがない場合でも、基本型の任意の値をenumにキャストできることに注意してください。したがって、スイッチのデフォルトセクションを常に使用することをお勧めします。ところで、.NET自体も浮動小数点値の列挙型を許可していますが、C#でそれらを定義することはできませんが、それらはまだ使用できます(スイッチを除く)。

さらに、列挙型を使用すると、型の安全性が向上します。メソッドのパラメーターとしてint定数などを使用する場合は、任意のint値でメソッドを呼び出すことができます。確かに、キャストによって列挙型でも発生する可能性がありますが、偶発的に発生することはありません。さらに悪いことに、パラメータの順序を混同する可能性があります。

void method(int a, int b) {...}

定数Aだけがaに入り、定数Bだけがbになる可能性がある場合、2つの異なる列挙型を使用すると、コンパイル中の誤用が明らかになります。


20

定数は、列挙型が特定の型である場合、変数が値を変更しない(コンパイラがその知識に基づいて最適化できる)ことを示す言語機能です。

定数は任意のデータ型にすることができますが、列挙型は列挙型です。

私は、列挙型を使用して、いくつかのオプションがあり、コードの可読性を向上させたいと考えています。つまり、トレースレベルを、値0、1、2のintとして、またはエラー、警告、情報としての列挙型として持つことができます。

列挙型には、ビット単位の演算子として使用する機能もあります。つまり、FontStyle.Bold | FontStyle.Italicは、太字および斜体フォントを提供します。


8

ロバートの答えに加えて:

  1. 名前付き値の有限セットにはenumを使用します。各シンボルの背後にある数値については特に気にしません(たとえば、レガシーシステムとの互換性のために、それらを強制する機能はまだあります)。

  2. ロバート:はい、列挙型はビットフィールドとして使用できます。Flags属性を使用します(列挙型のメンバーに適切な数値があることを確認してください)。


3

C#定数は、定義された名前を値に与えるという点で変数に似ています。ただし、いったん定義すると、定数に割り当てられた値は変更できないため、定数は標準変数とは異なります。定数の主な利点は、自己文書化コードを作成し、1か所でキー値を宣言できるため、値を更新してソフトウェアを再コンパイルする必要がある場合に簡単にメンテナンスできるようにすることです。

一方、列挙子リストはシーケンスと状態を定義するのに役立ちます。特に、それらの状態を自然に進行する場合に役立ちます。これは、リスト内の各定数をフォーマットし、その名前または値を使用して比較できるためです。列挙型を使用して、有効な値の限定されたセットを定義することもできます。


3

enum代わりに使用するときに便利なのconstは、の値を反復処理できることです。値enumを使ってそれを行うのははるかに困難constです。

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