実現したいこと
- 与えられた文字列が定義されてた列挙型に変換できない場合はnullを返したい
- 型パラメータ制約がEnumの場合はnull許容値でもnullが返せないのか確認したい
前提
文字列で与えられたコード(数値)を定義されている列挙型に変換する処理を書いています。
いろんな列挙型に対応する必要があるのでジェネリックメソッドを定義しています。
戻り値がnull許容値型ならdefaultでnullが返るものだと思っていたんですが、列挙型は0で返ってしまいます。
列挙型の値に0を定義しているものがあり、これではまずいのでどうしてもnullで返したいです。
戻り値nullはそもそも書けなくてどうしたらいいんだって感じです。
該当のソースコード
C#
1namespace Main; 2 3class Program 4{ 5 public static void Main() 6 { 7 var fruitsList = new List<Fruits?>(); 8 for(var i = 0; i < 10; i++) 9 { 10 fruitsList.Add(GetEnum<Fruits>(i.ToString())); 11 } 12 13 var nameList = new List<Name?>(); 14 for (var i = 0; i < 10; i++) 15 { 16 nameList.Add(GetEnum<Name>(i.ToString())); 17 } 18 19 var fruitsList2 = new List<Fruits?>(); 20 for (var i = 0; i < 10; i++) 21 { 22 fruitsList2.Add(GetStruct<Fruits>(i.ToString())); 23 } 24 25 var nameList2 = new List<Name?>(); 26 for (var i = 0; i < 10; i++) 27 { 28 nameList2.Add(GetStruct<Name>(i.ToString())); 29 } 30 31 var dates = new List<DateTime?>(); 32 for (var i = 0; i < 10; i++) 33 { 34 dates.Add(GetStruct<DateTime>(i.ToString())); 35 } 36 37 } 38 39 enum Fruits 40 { 41 Apple = 0, 42 Banana, 43 Orange, 44 } 45 46 enum Name 47 { 48 John = 1, 49 Mike, 50 Kate, 51 Jully 52 } 53 54 // 数値の文字列をT型に変換する 55 public static T? GetEnum<T>(string? s) where T : Enum 56 { 57 if(int.TryParse(s, out var value)) 58 { 59 var temp = (T)(object)value; 60 61 if(Enum.IsDefined(typeof(T), temp)) 62 { 63 return temp; 64 } 65 66 } 67 68 return default; 69 } 70 71 // 数値の文字列をT型に変換する 72 public static T? GetStruct<T>(string? s) where T : struct 73 { 74 Type type = typeof(T); 75 if (!type.IsEnum) throw new ArgumentException(nameof(T)); 76 77 if (int.TryParse(s, out var value)) 78 { 79 var temp = (T)(object)value; 80 81 if (Enum.IsDefined(typeof(T), temp)) 82 { 83 return temp; 84 } 85 86 } 87 88 return default; 89 } 90} 91 92
試したこと
あと型パラメータ制約をstructにしてnullを返す方法を見つけたんですけど、これでもいいのか見てほしいです。
public enum Hoge1 : long, public enum Hoge2 : ulong
とか定義できるので、int.TryParse のところは long.TryParse でだめなら ulong.TryParse という感じにするといいと思います。
あと、[Flags] はどう扱うのか気になります。
>int.TryParse のところは long.TryParse ~
あ! Enum.TryParse(type, s, out var value) でよかったみたいです。
string? が使えるということは、.NET 系だと思いますが、バージョンによって回答が変わるかもしれないので、明記してください。
>int.TryParse のところは
int.TryParseメソッドは数値に変換できたら何でもいいと思って使ってます。
>[Flags]はどう扱うのか
聞かれている内容がピンと来ていないんですけどビットフィールドのことは管変えていません。
>Enum.TryParse(type, s, out var value) でよかったみたいです。
Enum.TryParseメソッド使ってみたですんけど、文字列からの変換もいけるんですね。ここには書いていないんですけど、受け付けるコードは数値の文字列のみという仕様なのでダメみたいです。
enum に使えるのは SByte/Byte/Int16/UInt16/UInt32/Int32/UInt64/Int64 です。int 以外だと問題が出る可能性があります。
Flags というのは組み合わせて使うものなので(FontStyle.Regular | FontStyle.Italic) のような値は許可するのか、しないのかってことです。
数値しか許可しないのであれば、事前に数値であるかチェックしておけばいいと思います。
まぁそこまで考える必要がないのならOKです。
列挙型をByteで定義して256を引数に与えたらおっしゃる通りエラーが出たので正規表現で数値チェックをした後にEnum.TryParseメソッドにかけるようにしました。
教えていただきありがとうございます。

回答1件
あなたの回答
tips
プレビュー