Click here to Skip to main content
15,888,454 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I want to call Enum.TryParse<tenum> (string value, out TEnum result)

in a function that receives the type of the Enum as a parameter so i can call

the function with any enum type that i have declared in the code

something like that :

C#
void MyFunc(Enum someEnumType, string nameOfEnumValue,  out Enum value)
{
  Type TypeOfEnum = someEnumType.GetType();

  TypeOfEnum ePhaseOfSomeEnumType;

  Enum.TryParse<typeofenum>(nameOfEnumValue, out  ePhaseOfSomeEnumType);

  value = ePhaseOfSomeEnumType;
}


Thanks

What I have tried:

Searching google
Playing with GetType and Enum class
Posted
Updated 20-Aug-21 2:15am
v2
Comments
Richard MacCutchan 19-Aug-21 10:35am    
What is the problem?
dj4400 19-Aug-21 10:46am    
The snippet doesnt work :)
Richard MacCutchan 19-Aug-21 10:50am    
And what exactly does that mean?
PIEBALDconsult 19-Aug-21 12:20pm    
You're working too hard.
You might want to have a look at my : https://www.codeproject.com/Articles/23685/Enum-Utilities

MyEnum x ;
LibEnum.TryParse<myenum> ( "Value1" , out x ) ;
BillWoodruff 20-Aug-21 8:32am    
The compiler has to somehow get the Type of the Enum: imho, the best way to handle this is to use the generic flavor Enum.TryParse, as shown in my answer below.

Avoid use of reflection if possible !

Unfortunately, there isn't a non-generic overload of TryParse. Which means you'll need to use some reflection to invoke the method.

For example:
C#
public static class EnumExtensions
{
    public static bool TryParse(Type enumType, string value, bool ignoreCase, out Enum result)
    {
        if (enumType is null) throw new ArgumentNullException(nameof(enumType));
        if (!enumType.IsEnum) throw new ArgumentException("Not an enum type.", nameof(enumType));
        
        MethodInfo baseMethod = typeof(Enum).GetMethods(BindingFlags.Public | BindingFlags.Static)
            .Where(m => m.Name == nameof(Enum.TryParse))
            .First(m => m.GetParameters().Length == 3);
        
        MethodInfo realMethod = baseMethod.MakeGenericMethod(enumType);
        object[] parameters = new object[] { value, ignoreCase, null };
        bool parsed = (bool)realMethod.Invoke(null, parameters);
        result = parsed ? (Enum)parameters[2] : default;
        return parsed;
    }
    
    public static bool TryParse(Type enumType, string value, out Enum result)
    {
        if (enumType is null) throw new ArgumentNullException(nameof(enumType));
        if (!enumType.IsEnum) throw new ArgumentException("Not an enum type.", nameof(enumType));
        
        MethodInfo baseMethod = typeof(Enum).GetMethods(BindingFlags.Public | BindingFlags.Static)
            .Where(m => m.Name == nameof(Enum.TryParse))
            .First(m => m.GetParameters().Length == 2);
        
        MethodInfo realMethod = baseMethod.MakeGenericMethod(enumType);
        object[] parameters = new object[] { value, null };
        bool parsed = (bool)realMethod.Invoke(null, parameters);
        result = parsed ? (Enum)parameters[1] : default;
        return parsed;
    }
}
 
Share this answer
 
Comments
BillWoodruff 20-Aug-21 8:29am    
me curious: do you think the facility for using generic flavor TryParse, as shown in my answer here, meets the needs of the OP ?
Richard Deeming 20-Aug-21 8:53am    
My reading of the question was that the OP has a Type instance rather than a generic type parameter. Otherwise, they could use the Enum.TryParse<T> method directly, which would obviously be the best solution. :)
As far as I know, you can't use Enum.TryParse without knowing the type at compile time - enum's are pretty much syntactic sugar which compile to a value type (integer) and don't have all the "baggage" a full class would have including inheritance (which isn;t allowed for value types at all)

So you can't really use automated systems to do that, but it isn't difficult to do it manually: Enum.GetNames[^] and Enum.GetValues[^] should provide enough data.
Alternatively, you could look at how the system does it: Reference Source[^] but that may just show you why it's not something they felt would be necessary ... :laugh:

It's a little odd to even try to do that though - it's not something I've ever seen the need for!
 
Share this answer
 
Comments
BillWoodruff 20-Aug-21 8:28am    
me curious: do you think the facility for using generic flavor TryParse, as shown in my answer here, meets the needs of the OP ?
OriginalGriff 20-Aug-21 8:38am    
I'm not convinced he knows what he wants / is doing - he seems to want to pass an enum type name as a string at runtime and get a suitable output from that.

Which is a silly idea to my mind.
I've been using this without any problems:
public static class EnumExtensions
{
    public static T GetEnumValue<T>(this string valuename)
        where T : struct
    {
        T value = default(T);
    
        if(Enum.TryParse<T>(valuename, out value))
        {
            return value;
        }
    
        throw new ArgumentException($"{valuename} failed to convert to {typeof(T)}");
    }
}
Sample usage:
public enum TestEnum
{
    abcm = 4,
    def = 19
}

// in some method
TestEnum val1 = "def".GetEnumValue<TestEnum>();

// force an error
TestEnum val2 = "xxx".GetEnumValue<TestEnum>();
Note: now that there is an Enum constraint, why can't we use that here instead of 'struct ?
 
Share this answer
 
v2
Comments
dj4400 26-Aug-21 4:44am    
Thanks - this seems to be the solution I've looked for

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900