こんにちは。明月です。
この投稿はC#で列挙型(enum)を使う方法に関する説明です。
我々がプログラムを作成する時に、固定値を使う場合があります。その時に変数の定数化(値が変わらない変数)を通って値を定義して使います。
link - [C#] 3. プログラミングの始めと変数と定数を使う方法
using System;
namespace Example
{
class Program
{
// 定数設定
public const int TYPE1 = 1;
public const int TYPE2 = 2;
// 関数呼び出す。
private static void Print(int type)
{
// パラメータ値がTYPE1なら
if (type == TYPE1)
{
// コンソール出力
Console.WriteLine("Print Type1");
}
// パラメータ値がTYPE2なら
else if (type == TYPE2)
{
// コンソール出力
Console.WriteLine("Print Type2");
}
// その以外
else
{
// コンソール出力
Console.WriteLine("Other");
}
}
// 実行関数
public static void Main(string[] args)
{
// 関数呼び出す。
Print(TYPE1);
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
}
}
上の例をみればPrintという関数のパラメータのタイプがintタイプなのでただ、1や2を入れても問題なく作動します。
でも、実際のプロジェクトでコーディングする際にコード上でただ1や2で作成すると、次でコードを見る時に何の意味が分からない場合があります。それで意味を分かりやすくするために定数に変換して1や2の意味を分かるように作成します。
上の例では私がTYPE1とTYPE2の定数を作成して意味を作ることです。実際にもこのようによく作成しますが、それも可読性の限界があります。
using System;
namespace Example
{
class Program
{
// 定数設定
// typeAの定数
public const int ATYPE1 = 1;
public const int ATYPE2 = 2;
// typeBの定数
public const int BTYPE1 = 1;
public const int BTYPE2 = 2;
// 関数作成
private static void Print(int typeA, int typeB)
{
// typeAのパラメータ値がATYPE1なら
if (typeA == ATYPE1)
{
// コンソール出力
Console.WriteLine("Print AType - 1");
}
// typeAのパラメータ値がATYPE2なら
else if (typeA == ATYPE2)
{
// コンソール出力
Console.WriteLine("Print AType - 2");
}
// typeBのパラメータ値がBTYPE1なら
if (typeB == BTYPE1)
{
// コンソール出力
Console.WriteLine("Print BTYPE - 1");
}
// typeBのパラメータ値がBTYPE2なら
else if (typeB == BTYPE2)
{
// コンソール出力
Console.WriteLine("Print BTYPE - 2");
}
}
// 実行関数
public static void Main(string[] args)
{
// 関数呼び出す。
Print(ATYPE1, BTYPE1);
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
}
}
typeAのパラメータにはATYPE1とATYPE2を使ってtypeBのパラメータにはBTYPE1とBTYPE2を使います。
私がソースを読みやすいためにtypeAのパラメータの定数とtypeBのパラメータの定数を区分しておきました。でも、このパラメータのデータタイプはintタイプなので、区分してもtypeAパラメータにもBTYPE1やBTYPE2定数を使っても問題ありません。
でも、そのルールを従って作成しないと、後でソースを解析する立場で意味が可笑しくなります。可読性が悪くなることも当たり前です。
それを整理することが可能にするものが列挙型(enum)です。
using System;
namespace Example
{
class Program
{
// 列挙型 TypeA
enum TypeA
{
TYPE1,
TYPE2
}
// 列挙型 TypeB
enum TypeB
{
TYPE1,
TYPE2
}
// 関数作成
private static void Print(TypeA typeA, TypeB typeB)
{
// typeAのパラメータ値がTYPE1なら
if (typeA == TypeA.TYPE1)
{
// コンソール出力
Console.WriteLine("Print AType - 1");
}
// typeAのパラメータ値がTYPE2なら
else if (typeA == TypeA.TYPE2)
{
// コンソール出力
Console.WriteLine("Print AType - 2");
}
// typeBのパラメータ値がTYPE1なら
if (typeB == TypeB.TYPE1)
{
// コンソール出力
Console.WriteLine("Print BTYPE - 1");
}
// typeBのパラメータ値がTYPE2なら
else if (typeB == TypeB.TYPE2)
{
// コンソール出力
Console.WriteLine("Print BTYPE - 2");
}
}
// 実行関数
public static void Main(string[] args)
{
// 関数呼び出す。
Print(TypeA.TYPE1, TypeB.TYPE2);
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
}
}
定数を列挙型に纏めてTypeAのパラメータにTypeBを入れることや数の1を入れて間違いコーディングを作成することができないし、可読性が悪くならないことにして、綺麗なソースコードを作成することができます。
列挙型は単純な定数の値を処理することではなく、bit flag値を設定して、もっと読みやすいソースコードを作成することができます。
using System;
namespace Example
{
class Program
{
// ビット演算子の値で設定する。
enum TypeA
{
// 0000 0000
None = 0x00,
// 0000 0001
TYPE1 = 0x01,
// 0000 0010
TYPE2 = 0x02,
// 0000 0100
TYPE3 = 0x04,
// 0000 1000
TYPE4 = 0x08,
// 0001 0000
TYPE5 = 0x10,
// 0010 0000
TYPE6 = 0x20,
// 0100 0000
TYPE7 = 0x40,
// 1000 0000
TYPE8 = 0x80
}
// 関数作成
private static void Print(TypeA typeA)
{
// typeAのパラメータがTYPE1なら
if ((typeA & TypeA.TYPE1) != 0)
{
// コンソール出力
Console.WriteLine("Print AType - 1");
}
// typeAのパラメータがTYPE2なら
if ((typeA & TypeA.TYPE2) != 0)
{
// コンソール出力
Console.WriteLine("Print AType - 2");
}
// typeAのパラメータがTYPE3なら
if ((typeA & TypeA.TYPE3) != 0)
{
// コンソール出力
Console.WriteLine("Print AType - 3");
}
// typeAのパラメータがTYPE4なら
if ((typeA & TypeA.TYPE4) != 0)
{
// コンソール出力
Console.WriteLine("Print AType - 4");
}
// typeAのパラメータがTYPE5なら
if ((typeA & TypeA.TYPE5) != 0)
{
// コンソール出力
Console.WriteLine("Print AType - 5");
}
// typeAのパラメータがTYPE6なら
if ((typeA & TypeA.TYPE6) != 0)
{
// コンソール出力
Console.WriteLine("Print AType - 6");
}
// typeAのパラメータがTYPE7なら
if ((typeA & TypeA.TYPE7) != 0)
{
// コンソール出力
Console.WriteLine("Print AType - 7");
}
// typeAのパラメータがTYPE8なら
if ((typeA & TypeA.TYPE8) != 0)
{
// コンソール出力
Console.WriteLine("Print AType - 8");
}
}
// 実行関数
public static void Main(string[] args)
{
// 関数呼び出す。
Print(TypeA.TYPE1 | TypeA.TYPE4 | TypeA.TYPE7);
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
}
}
上の例はビットのTYPE1とTYPE4、TYPE7をOR演算処理してパラメータに渡して、AND演算処理してデータのflag情報を取得することができます。
つまり、一つの変数でflagの情報を格納、取得ができます。
using System;
namespace Example
{
class Program
{
// ビット演算子の値で設定する。
enum TypeA
{
// 0000 0000
None = 0x00,
// 0000 0001
TYPE1 = 0x01,
// 0000 0010
TYPE2 = 0x02,
// 0000 0100
TYPE3 = 0x04,
// 0000 1000
TYPE4 = 0x08,
// 0001 0000
TYPE5 = 0x10,
// 0010 0000
TYPE6 = 0x20,
// 0100 0000
TYPE7 = 0x40,
// 1000 0000
TYPE8 = 0x80
}
// 作成関数
private static void Print(TypeA typeA)
{
// コンソール出力(TypeAの列挙型をToStringすると列挙型の文字列が出力する。)
Console.WriteLine(typeA.ToString());
}
// 実行関数
public static void Main(string[] args)
{
// 関数呼び出す。
Print(TypeA.TYPE1);
// 任意のキーを押してください
Console.WriteLine("Press any key...");
Console.ReadLine();
}
}
}
ToString関数を利用すると列挙型の値ではなく、ソースに作成した列挙型の文字が出力します。
私は新入社員の際に先輩からプログラム作成する時に定数、変数の宣言の以外にソースで数字があればハードコーディングだし、設計およびコーディング失敗だと聞きながら学びました。(ハードコーディングというのはソースで数字があることの意味だけではありません。)
そのため、先輩がプログラム作成作業が終わるといつも定数と変数にデータを置換した記憶があります。でも、仕様によりがあるのでソースで数字があることで設計失敗ではありません。少し極端的だったんですね。
つまり、定数に置換することより数字の1のデータがもっと明確な場合もあります。なので仕様によりですね。凄く珍しいですが。
大きいプロジェクトは一人で作成する場合はありません。大きいプロジェクトじゃなくてもハードコーディングが多くなると作成した時期には分かるかも知らないけど、一か月だけ過ぎても分からなくなります。
そのため、ソース可読性は凄く重要です。可読性のため、コメントがありますが、ソースのすべてのところでコメントを付けることもできないし、コメントが多すぎるなら逆にソースが汚くなり、ソース可読性が悪くなります。
なので、ソース可読性のために列挙型は凄く重要な文法と言います。
ここまでC#で列挙型(enum)を使う方法に関する説明でした。
ご不明なところや間違いところがあればコメントしてください。
- [C#] 26. 例外処理(try ~ catch)する方法2019/07/16 00:59:34
- [C#] 25. イベント(event)キーワードを使い方2019/07/16 00:48:03
- [C#] 24. ラムダ式(匿名関数)とAction、Func関数を使い方、そしてクロージャ(Closure)2019/07/16 00:36:19
- [C#] 23. デリゲート(delegate)2019/07/15 02:25:26
- [C#] 22. インデクサー(indexer)を使う方法2019/07/13 01:06:04
- [C#] 21. C#のプロパティ(Property)2019/07/13 00:56:20
- [C#] 20. オブジェクト指向プログラミング(OOP)の4つの原則(カプセル化、抽象化、継承化、多相化(ポリモーフィズム))2019/07/12 00:17:35
- [C#] 19. 列挙型(enum)を使う方法2019/07/11 23:13:25
- [C#] 18. 構造体(Struct)、そして値型を参照するタイプ(Reference of value type)と参照型を参照するタイプ(Reference of reference type)2019/07/10 23:57:25
- [C#] 17. thisとbaseのキーワード2019/07/10 23:43:56
- [C#] 16. 継承禁止のキーワードのsealed2019/07/10 00:19:18
- [C#] 15. インタフェース(interface)2019/07/10 00:06:17
- [C#] 14. 抽象クラス(abstract)と抽象メソッド(abstract)、そして仮想関数(virtual)2019/07/08 23:04:09
- [C#] 13. クラスの継承と再定義(override)する方法、overrideとnewの差異2019/07/08 22:55:00
- [C#] 12. Staticとアクセス修飾子、そしてカプセル化2019/07/07 23:12:30
- check2024/04/10 19:03:53
- [Java] 64.Spring bootとReactを連結する方法(Buildする方法)2022/03/25 21:02:18
- [Javascript] Node.jsをインストールしてReactを使う方法2022/03/23 18:01:34
- [Java] 63. Spring bootでcronスケジューラとComponentアノテーション2022/03/16 18:57:30
- [Java] 62. Spring bootでWeb-Filterを設定する方法(Spring Security)2022/03/15 22:16:37
- [Java] JWT(Json Web Token)を発行、確認する方法2022/03/14 19:12:58
- [Java] 61. Spring bootでRedisデータベースを利用してセッションクラスタリング設定する方法2022/03/01 18:20:52
- [Java] 60. Spring bootでApacheの連結とロードバランシングを設定する方法2022/02/28 18:45:48
- [Java] 59. Spring bootのJPAでEntityManagerを使い方2022/02/25 18:27:48
- [Java] 58. EclipseでSpring bootのJPAを設定する方法2022/02/23 18:11:10
- [Java] 57. EclipseでSpring bootを設定する方法2022/02/22 19:04:49
- [Python] Redisデータベースに接続して使い方2022/02/21 18:23:49
- [Java] Redisデータベースを接続して使い方(Jedisライブラリ)2022/02/16 18:13:17
- [C#] Redisのデータベースを接続して使い方2022/02/15 18:46:09
- [CentOS] Redisデータベースをインストールする方法とコマンドを使い方2022/02/14 18:33:07