2017-09-01 14 views
2

jsonの入力を受け取り、正しい列挙型に解析しようとしています。私は3つの列挙型を持っています:文字列を一般的な列挙型に変換する

public class Enums 
{ 
    public enum Motivators{ 
     Small_Motivator, 
     Medium_Motivator, 
     Large_Motivator 
    } 

    public enum Reactors{ 
     Small_Reactor, 
     Large_Reactor 
    }   

    public enum Movers{ 
     Small_Mover, 
     Large_Mover 
    } 
} 

私は一般的な列挙型を取り、私たちが持っている型を調べるために解析します。

An exception of type 'System.ArgumentException' occurred in mscorlib.dll but was not handled in user code 

Additional information: Type provided must be an Enum. 
+0

'' WorkerType "の値を解析すると、すでに' WorkerType'列挙体の値であると予想されます。だから、属性から 'Dictionary'を対応する列挙型に使うの​​はなぜですか? – PoByBolek

答えて

1

あなたのenumインスタンスにstringを簡単に解析できます。しかし、enum型を定義する必要があります。

static void Main(string[] args) 
{ 
    string worker = "Small_Motivator"; 

    var provider = new EnumProvider(); 

    var enumValue = provider.GetByValue(worker); 
} 

public class EnumProvider 
{ 
    public object GetByValue(string sourceStr) 
    { 
     var enumTypes = new[] 
     { 
      typeof(Enums.Motivators), 
      typeof(Enums.Movers), 
      typeof(Enums.Reactors) 
     }; 

     foreach (var type in enumTypes) 
     { 
      var enumValues = Enum.GetValues(type) 
       .Cast<object>() 
       .Select(x => x.ToString()) 
       .ToArray(); 

      if (enumValues.Any(x => x == sourceStr)) 
      { 
       return Enum.Parse(type, sourceStr); 
      } 
     } 

     throw new ArgumentException($"{sourceStr} not supported"); 
    } 
} 
0
:その後、
{ 
    "WorkerType":"Small_Motivator" 
} 

とJSONを解析しよう

private void InitializeGenerator(Enum enumType) 
    { 
     if (enumType is Enums.Motivators) 
     { 
      // work work work work work  
     } 
     else if (enumType is Enums.Reactors) 
     { 
      // work  
     } 
     else if (enumType is Enums.Movers) 
     { 
      // work 
     } 
     else 
     { 
      // we dont know what it is 
     } 
    } 

次のようになります私のJSON ..

..

JObject jObject = JObject.Parse(json); 
JToken worker = jObject.GetValue("WorkerType"); 
Enum workerType = (Enum)Enum.Parse((typeof(Enum)), worker.ToString(), true); 
InitializeGenerator(workerType); 

は、次のエラーがスローされます

ここであなたが間違っていると思う:

Motivators workerType = (Motivators) Enum.Parse((typeof(Motivators)), worker.ToString(), true); 

worker.ToString()は "Small_Motivator" の一つ、 "Medium_Motivator"、 "Large_Motivator" でなければなりません。ここ

EDIT

これにあなたの列挙型クラスを変更:

public class Enums 
{ 
    public enum Motivators{ 
    Small_Motivator, 
    Medium_Motivator, 
    Large_Motivator 
    } 

    public enum Reactors{ 
    Small_Reactor, 
    Large_Reactor 
    }   

    public enum Movers{ 
    Small_Mover, 
    Large_Mover 
    } 
    public static Enum EnumFactory(string enum_string) { 
     if(enum_string.IndexOf("Motivator", StringComparison.OrdinalIgnoreCase) >= 0) { 
      return (Motivators) Enum.Parse((typeof(Motivators)), enum_string, true); 
     } 
     else if(enum_string.IndexOf("Reactor", StringComparison.OrdinalIgnoreCase) >= 0) { 
      return (Reactors) Enum.Parse((typeof(Motivators)), enum_string, true); 
     } 
     else if(enum_string.IndexOf("Mover", StringComparison.OrdinalIgnoreCase) >= 0) { 
      return (Movers) Enum.Parse((typeof(Motivators)), enum_string, true); 
     } 
     return null; 
    } 
} 

あなただけEnums.EnumFactory(worker.ToString())を呼び出すことができます。


、ここでオンラインのランタイム環境へのリンクです: link

+0

しかし、代わりにWorkerTypeがReactorまたはMoverの場合はどうなりますか?私はすべての列挙型を処理する方法が必要です。 –

+0

一般的に、Enumを解析する正しい方法を示したかったのですが、コードのロジックについては、時間がかかります。 – Moher

+0

事実は、 C#が 'Enum'のタイプを知りたいときに使います。文字列と一致する値を見つけようとすると、あなたのプロジェクトで(CLRはもちろん)Enum型をすべて調べることはできません。 –

0

あなたは、Enumにすべての列挙型の基本クラスをテキストことができません。 Enums.Motivatorsのようなより具体的なコンテキストを提供する必要があります。しかし、あなたのケースでは3種類の列挙型があるので、コンテキストがjsonにも格納されていない限り、Enum.Parseを使用することはできません。

しかし、あなたは、それぞれの列挙値にテキストをマッピングした辞書を生成することができます。

public class Enums 
{ 
    private static readonly IReadOnlyDictionary<string, Enum> mappings = typeof(Enums).GetNestedTypes() 
     .Where(x => x.IsEnum) 
     .SelectMany(x => x.GetEnumValues().Cast<Enum>()) 
     .ToDictionary(x => x.ToString(), x => x); 

    public static Enum Parse(string value) 
    { 
     Enum result; 
     if (!mappings.TryGetValue(value, out result)) 
      throw new ArgumentOutOfRangeException("Value: " + value); 

     return result; 
    } 

    // your enum types below... 
} 

使用法:

JObject jObject = JObject.Parse(json); 
JToken worker = jObject.GetValue("WorkerType"); 
InitializeGenerator(Enums.Parse(worker.ToString())); 
+0

また、' Enums' 'WorkerType'という名前に変更され、' static'として修飾されます。 – Xiaoy312

0

別のオプションは、ちょうど含むオブジェクトをシリアライズとデシリアライズすることです列挙型はXmlSerializerまたはJsonSerializerを使用します。

関連する問題