0

I found an edge case for enum values and want to know whether there is a solution for that problem in .net5

I´ve got the following enum:

public enum SomeEnum : ushort
{
    FirstValue = 0x9D80,
    SecondValue = 0x9DCE,
    ThirdValue = 0xEBA0,
    Unknown = 0xFFFF,
}

And want to know whether a given value is part of the enum and used Enum.TryParse but with the following Code it will always return true even 1 is not part of the enum:

Enum.TryParse<SomeEnum>("1", out _);

Thats because the following line does not corse an error:

var myEnum = (SomeEnum)1;

So I´ve changed to the Method Enum.IsDefined, so far so good the following code does deliver the desired results:

Enum.TryParse<SomeEnum>(myValue, out var x) && Enum.IsDefined(x);

But now the edge case is:

var myEnumValue = uint.Max;
Enum.TryParse<SomeEnum>(myValue.ToString(), out var x) && Enum.IsDefined(x);

Which delivers true because x = SomeEnum.Unknown and thats caused because IsDefined does a cast to ushort from uint.Max which is 0xFFFFFFFF to 0xFFFF. So I do not know how to check for any case whether a numeric value is part of a given enum.

Felix Arnold
  • 839
  • 7
  • 35
  • 1
    You'd probably have to test the type as well. Make sure `myEnumValue` is actually a `ushort`. – Andy Jul 11 '22 at 14:16
  • 3
    Was not able to reproduce. Both your code and `Enum.IsDefined(typeof(SomeEnum), uint.MaxValue.ToString())` returns `false` for me in .NET 5 solution I have. Which version of .NET 5 are you using? – Guru Stron Jul 11 '22 at 14:16
  • What about `Enum.GetValues().Any(x => (ushort)x == theUshortIWantToTest)`? For maximum performance, dump `Enum.GetValues().Select(x => (ushortx))` into a HashSet first (and only once). – Heinzi Jul 11 '22 at 14:17
  • @Andy I suppose that OP wants other values to be working. Like `0x0000FFFF` – Guru Stron Jul 11 '22 at 14:17
  • https://stackoverflow.com/questions/13248869/c-sharp-enum-contains-value – McNets Jul 11 '22 at 14:20
  • Does this answer your question? [How to check If a Enum contain a number?](https://stackoverflow.com/questions/12291953/how-to-check-if-a-enum-contain-a-number) and uint.Max should be uint.MaxValue – Piglet Jul 11 '22 at 14:24
  • Check if your variables are correct. You defined `SomeEnum` but your example uses `ProductNumber`. `uint.Max` doesn't exists, it should be `uint.MaxValue`. Also, you're defining `myEnumValue` but are trying to parse `myValue`. All of this are errors from when you post here or they're errors in you original code? – Magnetron Jul 11 '22 at 14:27
  • Enum.IsDefined takes two arguments. how does `Enum.IsDefined(x)` work for you? Also how does it cast to ushort? it should throw an exception for anything but a ushort. `Enum.IsDefined(typeof(SomeEnum), myValue)` should be all you need – Piglet Jul 11 '22 at 14:27
  • Its only a little because those answers does not wrap the (ushort)uint case but I´ve got a solution which works for me and my case. I parse the given numeric value into ulong or long, then check with `Enum.GetValues` whether the given value is in, for the last case I use the already given answer with `Enum.TryParse && IsDefined` – Felix Arnold Jul 11 '22 at 14:29
  • @Piglet OP is using [overload](https://learn.microsoft.com/en-us/dotnet/api/system.enum.isdefined?view=net-6.0#system-enum-isdefined-1(-0)) which takes 2 arguments. Only one of them is a generic type argument. – Guru Stron Jul 11 '22 at 14:29
  • 1
    @FelixArnold, if you use `Enum.IsDefined` without the `TryParse`, it does work. `IsDefined` actually throws an exception if the type (in your case `uint`) doesn't match the type of the enum (in your case `ushort`), so you'd just need to catch that exception, or check the types yourself upfront. Perhaps worth noting: you should pass in your number as a string to `IsDefined` because it will always return false (strings are only for named enum values). – Pooven Jul 11 '22 at 14:35

0 Answers0