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

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

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

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1304閲覧

ジェネリクスを使って1つの統一した処理を作りたいです。

ZheZephyrz

総合スコア11

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

1グッド

1クリップ

投稿2020/03/14 14:59

編集2020/03/14 15:28

前提・実現したいこと

 Unityです。ジェネリクスで取得したenumの引数を元に、enumの種類による分岐ではなく、ジェネリクスを使って1つの統一した処理を作りたいです。

発生している問題・エラーメッセージ

 enumの種類が増えてきたため、ジェネリクスを使用したメソッドを作ってenumの種類によって分岐し、対象の文字列をenumにして戻す処理を作りました。
このとき、enumの種類分だけif文による分岐を作成しているため、せっかくジェネリクスの形でenumを引数にもらっているのに非常に屈託な書式になってしまいました。
ジェネリクスを使って、分岐を作らずに引数よりenumを特定した1つの処理を作ることはできるのでしょうか。
またメソッドの呼び出しもキャストが必要なため、こちらも屈託です。
ご教示いただけますようお願い申し上げます。

エラーメッセージはありませんが、全体の処理も見て頂いて問題点があるようでしたらご教示頂けますと幸いです。

該当のソースコード

C#

1using System; 2using System.Linq; 3using UnityEngine; 4 5public class Test : MonoBehaviour { 6 7 public enum TIME_TYPE { 8 MORNING, 9 AFTERNOON, 10 EVENING, 11 NIGHT, 12 } 13 14 public enum DAY_TYPE { 15 SUNDAY, 16 MANDAY, 17 TUESDAY, 18 WEDNESDAY, 19 THURSDAY, 20 FRIDAY, 21 SATURDAY 22 } 23 24 public enum SERIES_TYPE { 25 PAST, 26 NOW, 27 FUTURE 28 } 29 30 public DAY_TYPE dayType; 31 public TIME_TYPE[] timeTypeArray; 32 33 void Start() { 34 // 文字列を引数で渡した種類のEnumに変換 35 string day = "friday"; 36 dayType = GetEnumTypeFromString(dayType, day); 37 38 // 配列の場合 39 string timeArray = "night,afternoon,morning"; 40 string[] strArray = timeArray.Split(',').ToArray(); 41 timeTypeArray = new TIME_TYPE[strArray.Length]; 42 for (int i = 0; i < strArray.Length; i++) { 43 timeTypeArray[i] = GetEnumTypeFromString(timeType, strArray[i]); 44 } 45 } 46 47 /// <summary> 48 /// stringをジェネリクスでもらったタイプのEnumにする 49 /// </summary> 50 public T GetEnumTypeFromString<T>(T t, string str) where T : struct { 51     // enumの種類の確認用 52 Type tempType = t.GetType(); 53 Debug.Log(tempType); 54 55 Type type = typeof(T); 56 if (!type.IsEnum) { 57 Debug.Log("Not Enum"); 58 } else { 59 if (type == typeof(TIME_TYPE)) { 60 TIME_TYPE temp = (TIME_TYPE)Enum.Parse(typeof(TIME_TYPE), str, true); 61 return (T)(object)temp; 62 } 63 if (type == typeof(DAY_TYPE)) { 64 DAY_TYPE temp = (DAY_TYPE)Enum.Parse(typeof(DAY_TYPE), str, true); 65 return (T)(object)temp; 66 } 67 if (type == typeof(SERIES_TYPE)) { 68 SERIES_TYPE temp = (SERIES_TYPE)Enum.Parse(typeof(SERIES_TYPE), str, true); 69 return (T)(object)temp; 70 } 71 } 72 return (T)(object)TIME_TYPE.AFTERNOON; 73 } 74} 75

試したこと

処理自体は問題なく動いています。

dayType:DAY_TYPE.FRIDAY, timeTypeArray[0]:TIME_TYPE.NIGHT, timeTypeArray[1]:TIME_TYPE.AFTERNOON, timeTypeArray[2]:TIME_TYPE.MORNING,

上記が変数内に格納されている値として確認できています。

GetEnumTypeFromString()メソッド内の下記のif文の分岐をなくして、1つの処理に統一したいと考えております。

if (type == typeof(TIME_TYPE)) { TIME_TYPE temp = (TIME_TYPE)Enum.Parse(typeof(TIME_TYPE), str, true); return (T)(object)temp; } if (type == typeof(DAY_TYPE)) { DAY_TYPE temp = (DAY_TYPE)Enum.Parse(typeof(DAY_TYPE), str, true); return (T)(object)temp; } if (type == typeof(SERIES_TYPE)) { SERIES_TYPE temp = (SERIES_TYPE)Enum.Parse(typeof(SERIES_TYPE), str, true); return (T)(object)temp; }

こちらをどのように修正したらよいのか、わからずにおります。
何卒よろしくお願い致します。

s.k👍を押しています

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

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

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

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

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

Zuishin

2020/03/14 15:43

この部分の TIME_TYPE, DAY_TYPE, SERIES_TYPE を全部 T に変えて望み通り動くかどうか確かめてみたらどうでしょうか。
Zuishin

2020/03/14 15:51 編集

無意味なコメントだったので削除。
guest

回答1

0

ベストアンサー

こんな感じでどうでしょう?

T func<T>(string str){ return (T)Enum.Parse(typeof(T), str, true); } enum XXX{ a, b, c}; var x = func<XXX>("a");

投稿2020/03/14 15:58

izmktr

総合スコア2856

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

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

draq

2020/03/15 02:36

変換できないことを考慮しなくていいなら、別メソッドにする必要も無くて、 Enum.TryParse<T>(value, out var result); を直接呼ぶだけでもいいですね。 Enum.Parse<T>があればもっと良かったんですが無いので。
ZheZephyrz

2020/03/15 04:54

>izmktrさま  ご回答頂きまして、ありがとうございます。 とても参考になります! 早速使わせて頂きますね。 >dragさま  ご回答頂きまして、ありがとうございます。 そうですね。本来であればそれで済んでしまうと思うのですが、何かジェネリクスを使ってできないものかと考えておりました。
ZheZephyrz

2020/03/15 10:22

おかげ様で、配列の場合が特に楽にかけるようになりました。 ``` void Start() { // 文字列を引数で渡した種類のEnumに変換 string day = "friday"; dayType = GetEnumTypeFromString<DAY_TYPE>(day); // 配列の場合 string timeArray = "night,afternoon,morning"; timeTypeArray = timeArray.Split(',').Select(GetEnumTypeFromString<TIME_TYPE>).ToArray(); } ```
Zuishin

2020/03/15 10:28

普通にやった方が楽だと思いますが。補完も効くし。 timeTypeArray = new[] { TIME_TYPE.NIGHT, TIME_TYPE.AFTERNOON, TIME_TYPE.MORNING };
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問