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

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

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

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

列挙型

データ型の一種で、要素・メンバなど名前のある値や、型の列挙子によって構成されます。

Q&A

解決済

1回答

1807閲覧

【C#】switch文で列挙子が見つからない件について

kazu0630

総合スコア26

C#

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

列挙型

データ型の一種で、要素・メンバなど名前のある値や、型の列挙子によって構成されます。

0グッド

0クリップ

投稿2021/10/18 05:54

編集2021/10/18 07:17

お世話になっております。

C#の学習をしております。

あるクラスで列挙型を定義し、他クラスのswitch文で列挙子を使用した際に、以下のようなエラーメッセージがでました。

エラー内容

原因と解決策をご教示いただけないでしょうか。

C#

1using System; 2using System.Collections.Generic; 3using System.Text; 4 5namespace C_Sharp_BUNPO.EnumTest 6 { 7 class Class1 8 { 9 public enum Number : int 10 { 11 NONE = 0, 12 13 ONE = 1, 14 15 TWO = 2 16 17 } 18 19 public void test() 20 { 21 Console.WriteLine(Number.ONE.ToString()); 22 } 23 } 24}

C#

1using System; 2using System.Collections.Generic; 3using System.Text; 4 5namespace C_Sharp_BUNPO.EnumTest 6{ 7 class Class2 8 { 9 public static void test() 10 { 11 Console.WriteLine(Class1.Number.ONE.ToString()); 12       13      // 修正 14 string val = 1; 15 16 switch(val) 17 { 18 case Class1.Number.ONE.ToString(): 19 break; 20 21 } 22 } 23 } 24}

【追記 環境】
「.NET Core3.1」「VisualStudio 2019」
プロジェクト構成

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

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

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

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

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

guest

回答1

0

ベストアンサー

こちらの環境で提示ソースを貼り付けすると、「CS0029 型 'string' を 'int' に暗黙的に変換できません」になりますが。Class1を含むソースが、プロジェクトから除外されていたりしませんか?

投稿2021/10/18 06:18

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kazu0630

2021/10/18 06:23

ご確認いただき、ありがとうございます。確認をしてみましたが、プロジェクトから除外されてはいないようです・・。
dodox86

2021/10/18 06:30

質問者さんのコードにはnamespaceの宣言がないので完全に同じではないかもですが、私の環境、Visual Studio 2019 では質問者さんのエラーと同じものが再現しました。(.NET Core 3.1コンソールプロジェクト) Class1.Number.ONEは enumですが、int valでswitchの評価をしようとするものの case ではToString()をしているので、C#コンパイラが混乱しているかんじがします。 ビルドを開始しました... 1>------ ビルド開始: プロジェクト: ConsoleApp2, 構成: Debug Any CPU ------ 1>C:\projects\ConsoleApp2\ConsoleApp2\Class2.cs(20,36,20,39): error CS0426: 型名 'ONE' が型 'Class1.Number' に存在しません 1>プロジェクト "ConsoleApp2.csproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
退会済みユーザー

退会済みユーザー

2021/10/18 06:39 編集

こちらはVS2017の.NET Framework4.6.1で試しました。 質問のSS見るとエディタに色はついているので、IDEでは認識しているっぽいですね。 いずれにしても、何故ToStringしてるのか?という疑問はありますけど。 ・valをClass1.Numberで宣言する ・(int)Class1.Number.ONE にする ・enumをクラスの外に出してみる とかやった場合は認識しますかね?
kazu0630

2021/10/18 06:41

申し訳ありません。ソースと画像の内容を修正致しました。 修正箇所は、switchの条件に使っている変数をint型ではなく、string型に変えてみました。 同様のエラーが出ているままです・・。
dodox86

2021/10/18 06:42

@radianさん radianさんが試された環境と同じVS2017/.NET Framework 4.6.1 のコンソールアプリケーションで作成してみたら、radianさんと同じエラーが出ました。面白いですね。(面白がっている場合ではない) @質問者kazu0630さん 実行している環境、Visual Studio のバージョンやプロジェクトの形態など、詳細な情報はなるべく質問本文中に示しましょう。
退会済みユーザー

退会済みユーザー

2021/10/18 06:46

> ソースと画像の内容を修正致しました。 一旦回答が付いたら質問を変更しないでください。質問と回答のつじつまが合わなくなって、自分のように後からここを見たものには訳が分からなくなります。修正ではなく追記にして、質問と回答を上から読んでいったときにつじつまが合うようにしてください。
dodox86

2021/10/18 06:50

@質問者さん radianさんの[2021/10/18 15:34]のコメント > いずれにしても、何故ToStringしてるのか?という疑問はありますけど。 に応える(意味を考える)ことが正しい対応への道すじになるはずです。.ToString()にするということは、caseにおいてstringで評価しようとしていることになります。が、そうではありませんね。Class1.Numberのenumなのかintなのかstringなのかちゃんと意識しなけりゃダメかと。
退会済みユーザー

退会済みユーザー

2021/10/18 07:02 編集

ソース修正したことで最初より酷い状態になって、他の箇所でもコンパイル通らなくなってないですか? あと、コメントした事試してみました?
kazu0630

2021/10/18 07:07

申し訳ありません。switch文と列挙型について、学習を再度やり直した方がよい状態で、質問をしてしまっている状態で質問をしていまい、状況をややこしくしてしまってますね・・。(その他、コードをいじっている過程でおかしくなったソースコードを添付してしまったこともややこしくしてしまっている原因です・・。 ToString()を加えた経緯としては、「C_Sharp_BUNPO。EnumTest.Class1.Numbeを'string' に暗黙的に変換できません」と出たため、String型じゃないといけないのかなと思って追加しただけになります・・。暗黙的に型変換できないなら、TOStringで明示的に型変換できないかと考えました。 ひとまず、ややこしくしてしまったため、整理させていただきますと、 ・列挙型はint型で定義 ・switch文の条件にはstring型の変数を設定 して条件分岐できたら・・と考えております。
kazu0630

2021/10/18 07:10

> radianさん 申し訳ありません。 名前空間とインポート箇所を追加したことで、名前空間のカッコが抜けておりました・・。大変申し訳ありません。
退会済みユーザー

退会済みユーザー

2021/10/18 07:24 編集

まず基本的な事として、列挙型は列挙型のまま扱いましょう。 caseは定数値判定しか扱えないので、ToString()した値は使えません。 数値を列挙型に変換する場合はキャストし、文字列を列挙型に変換する時はEnum.TryParseを使いましょう。 > **// 修正** これもコンパイルエラーです。
kazu0630

2021/10/18 07:32 編集

いろいろとご迷惑をおかけし申し訳ありません。 また親切なご回答、ありがとうございます。 ご回答いただいた内容、理解致しました。 本件の場合、実際に列挙型を使用したとき(例:Number.ONE)は、int型ではなく、列挙型名の型(今回の場合、Number)として扱われてしまうということですね。 最後の質問とさせていただきたいのですが、それでは列挙型宣言時に指定する型宣言は何のためにするものなのでしょうか。(列挙型でデータ型をint型として宣言した場合、int型ではなく、列挙型名の型として扱われるようなので、何のためにデータ型を定義したのか疑問に思いました。)
退会済みユーザー

退会済みユーザー

2021/10/18 07:38 編集

列挙型を数値としてDBやファイルに保存・復元する時や、他言語との連携時に便利になります。
kazu0630

2021/10/18 07:46

そういう時のために、型指定をしているのですね・・。 大変勉強になりました。 長い間お付き合いいただき、ありがとうございました。
TN8001

2021/10/18 09:02

> radianさんと同じエラーが出ました。面白いですね。(面白がっている場合ではない) パターンマッチングが入ったためですね。 C#6までは定数しか書けなかったわけですが、C#7から定数以外も来る可能性が出たため評価順?が変わったんだと思います。 LangVersionを6に落とすと、CS0426のほかにCS8059が2つ出ました。 エラー CS0426 型名 'NONE' が型 'Class1.Number' に存在しません エラー CS8059 機能 'パターン マッチング' は C# 6 では使用できません。7.0 以上の言語バージョンをお使いください。 エラー CS8059 機能 '再帰的パターン' は C# 6 では使用できません。8.0 以上の言語バージョンをお使いください。 どう再帰的パターンと勘違いしているかわかりませんが、class ToStringを作るサジェストが出たりとか面白いです^^; バグには違いないでしょうが、正しいエラー文を出すのも大変そうですね。。。
退会済みユーザー

退会済みユーザー

2021/10/18 11:09

> パターンマッチングが入ったためですね。 > C#6までは定数しか書けなかったわけですが、C#7から定数以外も来る可能性が出たため評価順?が変わったんだと思います。 ああ、そんなのがあるんですね。業務で主に使うのが.NET Framework4.6系なので、結構知識のアップデート追いついてない部分がありそう…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問