2017-09-01 130 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 
    } 
} 

我有,需要一个通用的枚举类型,分析检查,我们有哪些类型的方法。

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会是这个样子..

{ 
    "WorkerType":"Small_Motivator" 
} 

然后试图解析JSON ..

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

引发以下错误:

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

你可以很容易地解析字符串到你的枚举实例。但是你应该定义枚举类型

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

我想这里是你在做错的地方:

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

现在worker.ToString()必须是 “Small_Motivator”, “Medium_Motivator”, “Large_Motivator” 之一。

编辑

这里改变你的枚举类这样的:

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是一个反应堆或移动器会发生什么?我需要一种方法来处理所有枚举类型:) –

+0

我通常想告诉你解析一个枚举的正确方法,但对你的代码是需要更多的时间,虽然 – Moher

+0

的逻辑问题的事实是,有没有办法让C#知道你想要返回什么类型的'Enum'。它不会通过项目中所有的'Enum'类型(更不用说CLR),试图找到一个与字符串匹配的值... –

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枚举。