Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a non-generic version of Enum.TryParse #14083

Closed
yufeih opened this issue Feb 8, 2015 · 17 comments
Closed

Add a non-generic version of Enum.TryParse #14083

yufeih opened this issue Feb 8, 2015 · 17 comments
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime
Milestone

Comments

@yufeih
Copy link
Contributor

yufeih commented Feb 8, 2015

These are the methods in Enum class related to string parsing.

public static object Parse(Type enumType, string value);
public static object Parse(Type enumType, string value, bool ignoreCase);

public static bool TryParse<TEnum>(string value, out TEnum result) 
where TEnum : struct;
public static bool TryParse<TEnum>(string value, bool ignoreCase, out TEnum result) 
where TEnum : struct;

Apparently Parse is exposed only in non-generic form, while TryParse is only exposed in generic form. This is somewhat inconsistent.

It is simple enough to call a non-generic method in a generic method, but not the other way around. So Parse can be made generic using the following helper. But it is a lot harder to wrap TryParse into TryParse(Type enumType) without reflection calls.

public static TEnum Parse<TEnum>(string value, bool ignoreCase)
{
    return Enum.Parse(typeof(TEnum), value, ignoreCase);
}

The suggestion is to add a non-generic Enum.TryParse method, the API signature would look like

public static bool TryParse(Type enumType, string value, out object result) 
public static bool TryParse(Type enumType, string value, bool ignoreCase, out object result) 
@ellismg
Copy link
Contributor

ellismg commented Feb 8, 2015

Can you help me understand why you'd want the non generic version? What are the scenarios where you have an opaque type you know is an enum and a string and you need to parse it?

@yufeih
Copy link
Contributor Author

yufeih commented Feb 8, 2015

It is mostly for serialization, where the type of the enum is reflected and not fixed in the code upfront.

@miloush
Copy link
Contributor

miloush commented Jul 31, 2015

I agree I would find that helpful too. If a string is entered by user or otherwise received and the call site expects or looks for particular type of enum, you currently have to try/catch Parse, use reflection or GetNames and search manually, not sure which is worse performance-wise.

You especially can't use the generic overloads if you know the nullable version of the enum type. That is perfect use for the suggested TryCatch overload: you get the enum type with Nullable.GetUnderlyingType and you want to parse that enum type or return null when it fails.

@terrajobst
Copy link
Member

@ellismg are you opposed to having the non-generic version? I'm fine either way.

@KrzysztofCwalina @weshaggard any objections to the APIs as proposed?

@KrzysztofCwalina
Copy link
Member

No objections. Makes sense.

@weshaggard
Copy link
Member

agreed.

@SuperJMN
Copy link

SuperJMN commented Jan 8, 2016

I need this. I'm the author of OmniXAML (cross-platform XAML framework) and it would be useful to avoid extra calls like Enum.IsDefined

Parsing XAML requieres string values to be converted dynamically to their target types. When I want to convert to a Enum type, I know the type of the Enum and the string representation of the value that may or may not be a correct value, so a call like the propose (non-generic) should be added:

Enum.TryParse(Type enumType, string value)

@fruitbatinshades
Copy link

I need the same thing. In my use case I'm changing mixed property keys in a file format where they can add unknown keys for their own meta data. I read the property key and cast to the correct enum in a try/catch and only process the known ones. Being able to tryParse with a runtime type would help me out

@fruitbatinshades
Copy link

fruitbatinshades commented Jul 1, 2016

Can anyone see issues with this approach?

public static bool TryParseEnum(this string value, Type enumType,bool ignoreCase, out Enum enumValue) { if (Enum.IsDefined(enumType, value)) { enumValue = (Enum)Enum.Parse(enumType, value, ignoreCase); return true; } enumValue = null; return false; }

apart from not supporting flagged enums and I can't get markdown to indent the code :/

@yufeih
Copy link
Contributor Author

yufeih commented Jul 1, 2016

It does not respect ignoreCase and is not optimal because it compares the value twice.

@miloush
Copy link
Contributor

miloush commented Jul 1, 2016

Worse, it does not parse flags.
Edit: sorry, missed you mentioned that already - that is pretty severe limitation though

(To solve the problem of casing and two evaluations, you could implement the IsDefined method yourself using case insensitive index search on Enum.GetNames() and using that index into Enum.GetValues())

@terrajobst
Copy link
Member

Looks good; we should add both, the generic- and the non-generic forms so that Parse and TryParse have both versions.

@justinvp
Copy link
Contributor

justinvp commented Sep 8, 2016

Should there be a where TEnum : struct constraint on the proposed Parse<TEnum> to match the existing TryParse<TEnum>?

@yufeih
Copy link
Contributor Author

yufeih commented Sep 8, 2016

Yes, I will update the PR to corert.

@magol
Copy link

magol commented Sep 8, 2016

It is the same issue for Enum.ToObject

@justinvp
Copy link
Contributor

This issue can now be tagged as "api-needs-exposed".

@yufeih
Copy link
Contributor Author

yufeih commented Sep 26, 2016

What are the steps to expose an API like this?

Olafski referenced this issue in Olafski/corefx Jun 15, 2017
Fix typo in Fedora 26 in 2.0.0 preview 2 release notes. Thanks @omajid !
@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 2.0.0 milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Jan 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime
Projects
None yet
Development

No branches or pull requests