3

The following code does not compile in C# 7.3 even though it does support generics constrained to be enums:

using System;
public class Test<T> where T: Enum
{
    public void Method()
    {
        if (!Enum.TryParse<T>("something", out var value))
            throw new Exception("Oops");
    }
}

My other code that uses Enum constraints does work, so I have the right versions of everything, it just doesn't seem to be able to call another method that also is constrained to be an Enum.

Is this a bug or did I misunderstand how this is is supposed to work.

bikeman868
  • 2,236
  • 23
  • 30

1 Answers1

7

You need an extra constraint:

public class Test<T> where T: struct, Enum
{
    public void Method()
    {
        if (!Enum.TryParse<T>("something", out var value))
            throw new Exception("Oops");
    }
}

With just where T : Enum, you're allowed to call new Test<Enum>().Method(); -- i.e. pass in the Enum type, rather than any specific type of enum. Adding struct means you have to pass in a specific type of enum.

More specifically, Enum.TryParse<T> has the constraint where T : struct, so you need to match this constraint in your method.

canton7
  • 37,633
  • 3
  • 64
  • 77
  • [`TryParse` Code](https://github.com/microsoft/referencesource/blob/master/mscorlib/system/enum.cs#L333-L348) – ProgrammingLlama Aug 23 '19 at 08:18
  • That works. Can you explain why. Since `Enum.TryParse` has the same `where T: Enum` constraint I would expect this to work and find this result very surprising. – bikeman868 Aug 23 '19 at 08:18
  • @bikeman868 I've edited my answer. `Enum.TryParse` has the constraint `where T : struct`, not `where T : Enum` [see here](https://learn.microsoft.com/en-us/dotnet/api/system.enum.tryparse?view=netframework-4.8#System_Enum_TryParse__1_System_String___0__) – canton7 Aug 23 '19 at 08:22
  • I did some reading, and to clarify: `Enum` is a class but a specific type of enum is a `struct`. So the `Enum` constraint constrains it to the `Enum` class or a class that inherits from `Enum` and the additional `struct` constraint means that it must also be a `struct` and only specific enum types have these characteristics. – bikeman868 Aug 23 '19 at 08:47
  • @bikeman868 Yep, that's what my first paragraph tries to explain – canton7 Aug 23 '19 at 09:00
  • Your explanation made no sense to me until I went away and did some reading. The part that didn’t click with me from your explanation is that when I write public enum MyEnum {}, MyEnum is a struct that inherits from Enum which is a class. This is weird and counter intuitive for me. – bikeman868 Aug 24 '19 at 00:04