1

A simple class with a copy constructor, which calls another constructor:

public class Foo<TEnum> where TEnum : Enum
{
  public Foo(TEnum myEnum)
  {
    MyEnum = myEnum;
  }

  public Foo(Foo<TEnum> foo) : this(foo.MyEnum) { }

  public TEnum MyEnum { get; }
}

That would show warning:

warning CA1062: In externally visible method 'Foo{TEnum}.Foo(Foo{TEnum} foo)', validate parameter 'foo' is non-null before using it. If appropriate, throw an 'ArgumentNullException' when the argument is 'null'.

I ordinarily would do this:

public Foo(Foo<TEnum> foo)
  : this(foo?.MyEnum ?? throw new ArgumentNullException(nameof(foo))) { }

But that doesn't compile:

'TEnum' cannot be made nullable.

Am I missing something obvious or is this a limitation of some sort?

(I prefer not to suppress that warning as it's important; I'd like to do the validation somehow.)

1 Answer 1

3

You should also constrain TEnum to value types.

public class Foo<TEnum> where TEnum : struct, Enum

Then it can "be made nullable".

public Foo(Foo<TEnum> foo)
    : this(foo?.MyEnum ?? throw new ArgumentNullException(nameof(foo))) { }

Without the struct constraint, it is unknown whether TEnum is a value type or reference type. TEnum cannot be made nullable, because the nullable version of a type depends on whether it is a value type or reference type. If TEnum is a reference type, the nullable version will just be the type itself. If it is a value type, the nullable version will be System.Nullable<TEnum>.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Sweeper, once you pointed it out it became embarrassingly obvious. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.