Is there any way to combine these two methods into one method, or overloaded methods?

.net, c#, enums, generics

Solution

It requires couple additional type checks within the method and you have to skip generic constraint, but it's definitely possible:

public static T Parse<T>(object value)
{
    var isNullable = typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>);
    var itemType = isNullable ? typeof(T).GetGenericArguments()[0] : typeof(T);

    if (!itemType.IsEnum)
        throw new ArgumentException("T must be an Enum type or Nullable<> of Enum type.");

    if (value == null || value == DBNull.Value)
    {
        if (isNullable)
            return default(T);  // default(Nullable<>) is null

        throw new ArgumentException("Cannot parse enum, value is null.");
    }

    if (value is String)
    {
        return (T)Enum.Parse(itemType, value.ToString());
    }

    return (T)Enum.ToObject(itemType, value);
}

Sample usage:

var items = new object[] { "A", "B", 0, 10, null, DBNull.Value };

var results = items.Select(x => new { x, e = Parse<Test?>(x) }).ToArray();

foreach (var r in results)
    Console.WriteLine("{0} - {1}", r.x, r.e.ToString());

Prints

A - A
B - B
0 - A
10 - B
 -
 -

Problem

Here's a bit of a tricky one. Perhaps someone's C#-fu is superior to mine, as I couldn't find a solution. I have a method that takes a parameter that holds either an enum or a string indicating the value of an Enum and returns an instance of that enum. It's basically an implementation of `Enum.Parse` but implemented as a generic method. Why the .NET Framework doesn't have this built in is beyond me. ``` public static T Parse<T>(object value) where T : struct { if (!typeof (T).IsEnum) throw new ArgumentException("T must be an Enum type."); if (value == null || value == DBNull.Value) { throw new ArgumentException("Cannot parse enum, value is null."); } if (value is String) { return (T)Enum.Parse(typeof(T), value.ToString()); } return (T)Enum.ToObject(typeof(T), value); } ``` Now, I can do something like: ``` MyEnum foo = Parse<MyEnum>(obj); ``` And get an instance of `MyEnum`. If `obj` is null, I throw an exception. However, sometimes `obj` is `null` and I want to allow that. In this case, I'd like to be able to do: ``` MyEnum? foo = Parse<MyEnum?>(obj); ``` However, for the life of me, I can't figure out a way to get that working. First off, even though `Nullable<MyEnum>` is a `struct`, it's unable to be used as a type parameter to `Parse<T>`. I think this has something to do with all the magic the compiler does with `Nullable<>`, so I won't question it. It doesn't appear you can overload the method and only differentiate it based on constraints on `T`. For example, if I do: ``` public static T Parse<T>(object value) where T : new() { // This should be called if I pass in a Nullable, in theory } ``` I'll get the error: Member with the same signature is already declared So, that leaves me with only one option left: Implement a entirely separate method designed for nullable types: ``` public static T? ParseNullable<T>(object value) where T : struct { if (!typeof (T).IsEnum) throw new ArgumentException("T must be an Enum type."); if (value == null || value == DBNull.Value) return null; if (value is String) return Enum.Parse(typeof (T), value.ToString()) as T?; return Enum.ToObject(typeof (T), value) as T?; } ``` I can now call this with: ``` MyEnum? foo = ParseNullable<T>(obj); ``` My Question: Is there a way to combine these two methods into a single method that will do the right thing depending on the type parameter, or create overloads where one overload will be used in the case where the type parameter is Nullable<> and the other overload called when it's not?

Original source

Related problems