将字符串解析为通用枚举类型

时间:2017-09-01 20:50:16

标签: c# json enums

我正在尝试获取一些json输入并解析为正确的枚举类型。我有3个Enum类型:

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.

4 个答案:

答案 0 :(得分: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");
    }
}

答案 1 :(得分: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

答案 2 :(得分: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()));

答案 3 :(得分:0)

另一种选择是使用XmlSerializer或JsonSerializer序列化和反序列化包含枚举的对象。