質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

5703閲覧

C# の enum列挙型に関して

mugicya

総合スコア1046

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2017/06/22 11:19

こんにちわ。

C#の列挙型である enumですが、基となる型を指定できると思うのですが、
何を指定(名前の型とは別)しようが結局代入時にキャストする事になります。

enum Name : byte { mugicya = 0 }

で定義しても

byte b = (byte)mugicya;

となります。microsoft のリファレンスにも書いてあります。

C#リファレンスenum

基本型オプションを使用して enum 型をメンバーに持つ longを宣言しています。 列挙型の基になる型が longであっても、列挙型メンバーはキャストを使用して long 型に明示的に変換する必要があることにご注意ください。

なぜこんな面倒な仕様なのか、情報をご教示頂けると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

情報を持ってるわけじゃあないんですが、一応僕の理解を書いておきましょう。
スタックオーバーフローの答えなんかも見てきましたがそんなに違う考えではありませんでしたし。
https://stackoverflow.com/questions/4728295/why-enums-require-an-explicit-cast-to-int-type
https://stackoverflow.com/questions/11968868/why-do-we-need-to-type-cast-an-enum-in-c-sharp

enumは列挙に特化しています。
C++からだと「列挙するとはつまり順番に1,2,3と振る事だよね?」というイメージがあると思いますが、C#の列挙値は違います。
列挙するとは、別々のものとして識別できることであって、数値に変換できることではないんです。

本来の利用目的が識別することなのだから、暗黙的な型キャストはその考えと相反してしまうんですよね。

例えば下記の例で男が0で女が1というのは本来意識すべきことじゃあないんです。

C#

1enum 性別 2{ 3, 45}

男は男、女は女です。
もしも、特殊な目的(シリアライズ等)によって特定の型の特定の値を保持しなければならないのなら、それはconstの方がふさわしいと思います。

C#

1public static class Name 2{ 3 public const byte mugicha = 0; 4}

これならば最初から特定の型として扱うことを目的にしているわけです。
列挙するというのはそもそも「値が破壊されやすい性質」であることに留意しておく必要があります。
必ず値を指定しなければならないconst値の方がそういう意味では安定しています。
ほぼそういった値は、後から値が変化してはならないはずですからね。

enumはenumとして扱うことを前提に組まれている。
そういう風に僕は考えてます。

投稿2017/06/23 08:46

haru666

総合スコア1591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mugicya

2017/06/23 12:32

ありがとうございます。 型で宣言した場合の「性別」変数に代入する場合はキャストが必要ないのに、 enum 性別 : int と基となる型を指定した場合でも、int の変数に代入する場合でもキャストが必要というのが 疑問だったのです。 仰るように、static class で const 値を宣言したほうが、僕の求めている形…なのかもしれません。
guest

0

ベストアンサー

型安全のためといえると思います。

C言語だとenumをintへそのまま代入できます。使い勝手がよいと考えることもできますが逆に言えば
「この変数へは特定のenum型の値のみを設定したい。間違って整数型の値を設定しようとしたとき、それをプログラムの誤りとしてコンパイラーに検出してほしい。しかしCではenumとintの区別がないのでコンパイラーは何も言ってくれない」という不満も出てきます。

それに対してC#ではenum型とそれの基となった整数型は別の型として扱われ相互に自動変換されないため型安全なプログラミングがやりやすいです。

投稿2017/06/22 11:30

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mugicya

2017/06/23 12:25

ありがとうございます。 enum mugicya : int と指定して、ほかの型に代入する際にキャストが必要なのは理解しますが、 型指定させておいて、同一型の変数代入になぜキャストが必要なのか…という所でなんでかなあと。
KSwordOfHaste

2017/06/23 13:05 編集

enum Name : byteとあるとき、 (A)byteへNameを代入 (B)Nameへbyteを代入 のうち、Nameはbyteを派生しているように見えるので、(A)ができないのがおかしいと感じる気持ちはわかります。(B)ができないのは納得ですよね? (A)については自分は「Nameはbyteを派生しているのではなく、単にbyteと同じサイズということを表現しているに過ぎない」と考えています。要するに「継承に見えるけど、実は継承ではない」C#のチョットした文法上・意味上の不整合的だと思っています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問