例外処理は重いのでEnum.TryParseを用いたほうが良い
定義した Enum のメンバーに例えば入力した文字列が合致した場合に変換するといったケースはよくあります。
そういった場合に使えるメソッドが標準で用意されています。
文字列表現を Enum に変換するメソッド
-
- Parse は戻り値として変換結果を返します。変換出来ない場合は、例外を返すメソッドです。
-
- TryParse は変換出来ない場合は、戻り値として bool を返します。
使用例
ここでは Enum として元素記号(H, He, Li, Be...と元素番号順)を定義します。
- 入力
- 出力
- 存在した場合はそのメンバーと存在しない場合は 0 を返す、という仕様とします。
ChemicalElementsクラスは下記となります。
static class ChemicalElements { /// <summary> /// 元素記号 /// </summary> public enum SymbolsOfElements { H = 1, He, Li, Be, B, C, N, O, F, Ne, Na, Mg, Al, Si, P, S, Cl, Ar, K, Ca, Sc, Ti, V, Cr, Mn, Fe, Co, Ni, Cu, Zn, Ga, Ge, As, Se, Br, Kr, Rb, Sr, Y, Zr, Nb, Mo, Tc, Ru, Rh, Pd, Ag, Cd, In, Sn, Sb, Te, I, Xe, Cs, Ba, La, Ce, Pr, Nd, Pm, Sm, Eu, Gd, Tb, Dy, Ho, Er, Tm, Yb, Lu, Hf, Ta, W, Re, Os, Ir, Pt, Au, Hg, Tl, Pb, Bi, Po, At, Rn, Fr, Ra, Ac, Th, Pa, U, Np, Pu, Am, Cm, Bk, Cf, Es, Fm, Md, No, Lr, Rf, Db, Sg, Bh, Hs, Mt, Ds, Rg, Cn, Nh, Fl, Mc, Lv, Ts, Og, }; /// <summary> /// Enum.Parse による実装 /// </summary> /// <param name="name"></param> /// <returns></returns> static public SymbolsOfElements GetSymbolParse(string name) { SymbolsOfElements symbol; try { symbol = (SymbolsOfElements)Enum.Parse(typeof(SymbolsOfElements), name); } catch { symbol = 0; } return symbol; } /// <summary> /// Enum.TryParse による実装 /// </summary> /// <param name="name"></param> /// <returns></returns> static public SymbolsOfElements GetSymbolTryParse(string name) { SymbolsOfElements symbol; Enum.TryParse(name, out symbol); return symbol; } }
上記クラスを利用するクラスは下記のような形です。
class Program { static void Main(string[] args) { Stopwatch sw = new Stopwatch(); // A から Z までの文字列配列を作成する var alphabets = Enumerable.Range(0, 26).Select( n => ((char)('A' + n)).ToString() ); // TryParse による処理 Console.WriteLine("処理開始 [TryParse実装] ..."); sw.Start(); for (int i = 0; i < 100; i++) { foreach (var alphabet in alphabets) { var symbol = ChemicalElements.GetSymbolTryParse(alphabet); } } sw.Stop(); Console.WriteLine($"処理時間: {sw.Elapsed}\n"); // Parse による処理 Console.WriteLine("処理開始 [Parse実装] ..."); sw.Restart(); for (int i = 0; i < 100; i++) { foreach (var alphabet in alphabets) { var symbol = ChemicalElements.GetSymbolParse(alphabet); } } sw.Stop(); Console.WriteLine($"処理時間: {sw.Elapsed}\n"); Console.Read(); } }
実行結果
処理開始 [TryParse実装] ... 処理時間: 00:00:00.0036813 処理開始 [Parse実装] ... 処理時間: 00:00:05.8251481
いずれも同じ結果となる処理が、TryParseの場合は、4ms 未満に対し、Parseの場合は、5.8秒となりました。 1500倍くらい差がありますね。
例外処理は重いので Enum.TryParse を用いましょう。