5

I'm writing some Enum functionality, and have the following:

public static T ConvertStringToEnumValue<T>(string valueToConvert, 
    bool isCaseSensitive)
{
    if (String.IsNullOrWhiteSpace(valueToConvert))
        return (T)typeof(T).TypeInitializer.Invoke(null);

    valueToConvert = valueToConvert.Replace(" ", "");
    if (typeof(T).BaseType.FullName != "System.Enum" &&
        typeof(T).BaseType.FullName != "System.ValueType")
    {
        throw new ArgumentException("Type must be of Enum and not " +
            typeof (T).BaseType.FullName);
    }

    if (typeof(T).BaseType.FullName == "System.ValueType")
    {
        return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)),
            valueToConvert, !isCaseSensitive);
    }

    return (T)Enum.Parse(typeof(T), valueToConvert, !isCaseSensitive);
}

I now call this with the following:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>("Cat");

This works as expected. However, if I run this:

EnumHelper.ConvertStringToEnumValue<Enums.Animals?>(null);

it breaks with the error that the TypeInitializer is null.

Does anyone know how to solve this?

Thanks all!

6
  • 1
    Why on earth are you invoking the type initializer?? In my 9 years of C#, I have never needed to do that! Commented Sep 28, 2010 at 8:37
  • In fact that type initializer does not even return anything. The code is bogus, sorry. Commented Sep 28, 2010 at 8:38
  • 1
    @leppie, hence my posting of the question. I am looking for a way to do the above, and clearly the TypeInitializer isn't the correct way of doing this. The below answer from Preet is what I was looking for. Commented Sep 28, 2010 at 8:51
  • @leppie: he's asking a question to find a better way. Isn't that what SO is all about? Why so admonishing? Commented Sep 28, 2010 at 9:12
  • May i suggest you read up on the Type API. You should avoid using string comparison on types. For instance, typeof(T).BaseType.FullName != "System.Enum" may be better written as !typeof(T).IsEnum. Also typeof(T).BaseType.FullName != "System.ValueType" may be better written as !typeof(T).IsValueType. Commented Sep 28, 2010 at 9:23

4 Answers 4

10

try

if (String.IsNullOrWhiteSpace(valueToConvert))
              return default(T);
Sign up to request clarification or add additional context in comments.

Comments

1

I have an different approach, using extension and generics.

public static T ToEnum<T>(this string s) {
    if (string.IsNullOrWhiteSpace(s))
        return default(T);

    s = s.Replace(" ", "");
    if (typeof(T).BaseType.FullName != "System.Enum" &&
        typeof(T).BaseType.FullName != "System.ValueType") {
        throw new ArgumentException("Type must be of Enum and not " + typeof(T).BaseType.FullName);
    }

    if (typeof(T).BaseType.FullName == "System.ValueType")
        return (T)Enum.Parse(Nullable.GetUnderlyingType(typeof(T)), s, true);

    return (T)Enum.Parse(typeof(T), s, true);
}

Use like this...

Gender? g = "Female".ToEnum<Gender?>();

Comments

0

This one gets the job done and it also looks pretty. Hope it helps!

    /// <summary>
    /// <para>More convenient than using T.TryParse(string, out T). 
    /// Works with primitive types, structs, and enums.
    /// Tries to parse the string to an instance of the type specified.
    /// If the input cannot be parsed, null will be returned.
    /// </para>
    /// <para>
    /// If the value of the caller is null, null will be returned.
    /// So if you have "string s = null;" and then you try "s.ToNullable...",
    /// null will be returned. No null exception will be thrown. 
    /// </para>
    /// <author>Contributed by Taylor Love (Pangamma)</author>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="p_self"></param>
    /// <returns></returns>
    public static T? ToNullable<T>(this string p_self) where T : struct
    {
        if (!string.IsNullOrEmpty(p_self))
        {
            var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
            if (converter.IsValid(p_self)) return (T)converter.ConvertFromString(p_self);
            if (typeof(T).IsEnum) { T t; if (Enum.TryParse<T>(p_self, out t)) return t;}
        }

        return null;
    }

https://github.com/Pangamma/PangammaUtilities-CSharp/tree/master/src/StringExtensions

Comments

0

this is what I using, maybe useful for someone!

public static class EnumExtension
{
    public static TEnum? ParseOrDefault<TEnum>(string value, bool ignoreCase = false, TEnum? @default = default)
        where TEnum : struct, Enum
    {
        TEnum? @enum;
        try { @enum = (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase); }
        catch { @enum = @default; }
        return @enum;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.