kofifus
kofifus

Reputation: 19295

Generic string to enum conversion

Suppose enum:

public enum SysLogsAppTypes { None, MonitorService, MonitorTool };

and here is a function to convert from the ToString() representation back to enum:

private SysLogsAppTypes Str2SysLogsAppTypes(string str)  
{  
    try  
    {  
        SysLogsAppTypes res = (SysLogsAppTypes)Enum
                                       .Parse(typeof(SysLogsAppTypes), str);  
        if (!Enum.IsDefined(typeof(SysLogsAppTypes), res)) 
            return SysLogsAppTypes.None;  
        return res;  
    }  
    catch  
    {  
    return SysLogsAppTypes.None;  
    }  
}  

Is there a way to make this Generic ??

I tried:

private T Str2enum<T>(string str)   
{  
    try  
    {  
        T res = (T)Enum.Parse(typeof(T), str);  
        if (!Enum.IsDefined(typeof(T), res)) return T.None;  
        return res;  
    }  
    catch  
    {  
        return T.None;  
    }  
}  

but I get: 'T' is a 'type parameter', which is not valid in the given context
where there is T.None

Any help ? Thanks

Upvotes: 21

Views: 8699

Answers (5)

raffanacho
raffanacho

Reputation: 1

I don't know if this is still relevant in 2024 (maybe some current C# features already solve this with Generics). But here is my simple solution:

public static class EnumHelper
{
    public static T ToEnum<T>(this string value)
    {
        return (T)Enum.Parse(typeof(T), value);
    }
}

And then you can just use it like this:

public enum Categories
{
  One,
  Two,
  Three
}

var text = "One";
var enumvalue = text.ToEnum<Categories>();

Upvotes: 0

RoLYroLLs
RoLYroLLs

Reputation: 3215

I know this is old, but based on a few samples, I've researched along with @Simon_Weaver's solution, this is what I have:

public static T TryParse(String value, T defaultValue) where T : struct {
    if (String.IsNullOrWhiteSpace(value)) {
        return defaultValue;
    }

    T result;
    if (!Enum.TryParse(value, out result)) {
        if (Enum.IsDefined(typeof (T), result) | result.ToString().Contains(",")) {
            // do nothing
        } else {
            result = defaultValue;
        }
    } else {
        result = defaultValue;
    }

    return result;
}

Upvotes: 1

Simon_Weaver
Simon_Weaver

Reputation: 145950

I like to add in a defaultValue parameter for an overload of my TryParse for cases where I want a default if it can't be parsed or is null. This is most useful for parsing string.Empty or null.

Note: this implementation will revert to defaultValue if a junk value is passed in - so you may want to tweak that by throwing an exception.

public static T TryParse<T>(string value, T defaultValue) where T: struct
    {
        if (string.IsNullOrWhiteSpace(value))
            {
                return defaultValue;
            }

            T result;
            if (Enum.TryParse<T>(value, out result))
            {
                return result;
            }
            else
            {
                return defaultValue;  // you may want to throw exception here
            }
        }
    }


    ConverterMode mode = EnumUtils<ConverterMode>.TryParse(stringValue, ConverterMode.DefaultMode);

Upvotes: 4

Charles Bretana
Charles Bretana

Reputation: 146499

Not the way you are trying it, but I use the method below to do this:

 public static bool EnumTryParse<E>(string enumVal, out E resOut) 
        where E : struct
 {
      var enumValFxd = enumVal.Replace(' ', '_');
      if (Enum.IsDefined(typeof(E), enumValFxd))
      {
          resOut = (E)Enum.Parse(typeof(E), 
             enumValFxd, true);
          return true;
      }
      // ----------------------------------------
      foreach (var value in
          Enum.GetNames(typeof (E)).Where(value => 
              value.Equals(enumValFxd, 
              StringComparison.OrdinalIgnoreCase)))
      {
          resOut = (E)Enum.Parse(typeof(E), value);
          return true;
      }
      resOut = default(E);
      return false;
 }

No exceptions thrown here ...

Upvotes: 5

jball
jball

Reputation: 25014

I think the default keyword is what you need:

private T Str2enum<T>(string str) where T : struct
{   
    try   
    {   
        T res = (T)Enum.Parse(typeof(T), str);   
        if (!Enum.IsDefined(typeof(T), res)) return default(T);   
        return res;   
    }   
    catch   
    {   
        return default(T);   
    }   
}   

Upvotes: 19

Related Questions