Add Enum.Parse<T>() polyfill for .NET Framework builds (#5100)#5102
Add Enum.Parse<T>() polyfill for .NET Framework builds (#5100)#5102stevenaw merged 12 commits intonunit:mainfrom
Conversation
|
If you run |
stevenaw
left a comment
There was a problem hiding this comment.
Thanks for your interest and prompt PR @shaig-mahmudov.
I've left a few suggestions on how to adjust the code a bit which should allow this to seamlessly "just work".
Terje has also left a few suggestions on how to build and test this locally. There's a few build warnings (which you may be able to see in your IDE too) which are being escalated to errors by our CI build.
|
|
||
| using System; | ||
|
|
||
| namespace NUnit.Compatibility |
There was a problem hiding this comment.
This might be a "miss" on my part in the original spec. There's ambiguity errors reported by the compiler. You can likely help make them go away by changing this namespace to System so that it matches the namespace of the built-in Enum type.
| /// <typeparam name="T">The enum type to which to convert.</typeparam> | ||
| /// <param name="value">The string representation of the enumeration name or underlying value.</param> | ||
| /// <returns>An object of type T whose value is represented by value.</returns> | ||
| public static T Parse<T>(string value) where T : struct |
There was a problem hiding this comment.
If you convert this to use the C#14 extension member syntax then you can extend static methods onto Enum itself, similar to how we've added some of the classic asserts back onto the Assert class here: https://github.com/nunit/nunit/blob/main/src/NUnitFramework/nunit.framework.legacy/ClassicAssertExtensions.cs#L13-L19
Doing this will then allow you the update elsewhere in the code where we call Enum.Parse(typeof(EnumType), string) to instead call the generic Enum.Parse<EnumType>(string) method seamlessly
| /// Provides a polyfill for the generic Enum.Parse{T} method which is available in | ||
| /// .NET Core and newer .NET versions but missing in .NET Framework. | ||
| /// </summary> | ||
| internal static class Enum |
There was a problem hiding this comment.
I'd recommend renaming this to EnumExtensions so that changing the namespace to System doesn't cause conflicts
There was a problem hiding this comment.
Hi @stevenaw, I’ve applied the requested changes:
• Namespace: moved from NUnit.Compatibility to System to match the built-in Enum type and avoid ambiguity.
• Extension syntax: updated the implementation to use extension members so Enum.Parse() works seamlessly.
• Class name: renamed to EnumExtensions to avoid potential conflicts.
• Formatting: adjusted generic constraints (SA1127) to match the style guide.
• Local build: verified with dotnet build and dotnet build src/NUnitFramework/framework/nunit.framework.csproj across the relevant target frameworks.
Thanks for the guidance — happy to make further adjustments if needed.
There was a problem hiding this comment.
@shaig-mahmudov Look at the code @stevenaw linked to, or just see image below:

This is the new syntax, and then you get rid of the this Enum _ too.
There was a problem hiding this comment.
Thanks for your changes @shaig-mahmudov
Terje is right about the new syntax as it will allow these methods to appear as if they are static methods on the built-in Enum class itself despite that they aren't "built-in" on .NET Framework. The goal behind a polyfill like this is to allow code to call a method on all runtimes we support even if it's only built into .NET itself on newer ones.
In other words, we'd want to also able to update these references within this PR:
To instead call
Enum.Parse<RuntimeType>(s, true)Enum.Parse<InternalTraceLevel>((string)traceLevelValue, true)
As appropriate without needing any #if NETFRAMEWORK checks around where we call the method.
|
@dotnet-policy-service agree |
|
Hi @stevenaw, @TerjeP, I've updated the Enum.Parse polyfill as suggested:
|
|
Thanks @shaig-mahmudov |
…g-mahmudov/nunit into feature/enum-parse-polyfill Merge upstream changes into enum-parse-polyfill branch
|
@stevenaw Thanks for the feedback. I’ve updated the enum parsing in |
|
Thanks @shaig-mahmudov ! Your changes look good, I appreciate your quick responses to each feedback. Thanks for your contribution! |
|
@stevenaw Thanks for the review, edits, and guidance! I appreciate it and I’m happy to contribute to the project. |
Added a generic
Enum.Parse<T>polyfill in theNUnit.Compatibilitynamespace, wrapped in a#if NETFRAMEWORKconditional. This allows the framework to use the generic API on.NET Frameworkbuilds where it is not natively available. Closes #5100