Generic Constraint for Non Nullable types

15,429

Solution 1

Applying where T : struct applies a generic constraint that T be a non-nullable value type. Since there are no non-nullable reference types, this has the exact same semantics as simply "all non-nullable types". Nullable value types (i.e. Nullable<T>) do not satisfy the struct generic constraint.

Solution 2

From C# 8.0 you can now use the where T : notnull generic constraint to specificy T is a non-nullable type.

Share:
15,429
Matias Cicero
Author by

Matias Cicero

Software Development Engineer @ Amazon Web Services

Updated on June 15, 2022

Comments

  • Matias Cicero
    Matias Cicero almost 2 years

    I have the following class:

    public class KeyDTO<T>
    {
         public T Id { get; set; }
    }
    

    So far so good, but I want the type parameter T to be a non-nullable type. I've read somewhere that this may be feasible:

    public class KeyDTO<T> where T : IComparable, IComparable<T>
    {
         public T Id { get; set; }
    }
    

    But, If i change public T Id to public T? Id, I get a compilation error telling me that T must be non-nullable.

    How can I specify that a generic type parameter must be non-nullable?

    Edit

    I want to accomplish this because I want to annotate my Id property with the [Required] attribute as follows:

    public class KeyDTO<T> {
        [Required]
        public T Id { get; set; }
    }
    

    What [Required] does is validate the model so T cannot be null.

    However, if I have KeyDTO<int>, Id will be initialized to 0, bypassing my [Required] attribute

  • Christos
    Christos over 9 years
    Good explanation (+1). But I have a question: din't Nullable<T> requires where T : struct. Isn't a problem. Thank you in advance.
  • Servy
    Servy over 9 years
    I have no idea what you're trying to ask.
  • Christos
    Christos over 9 years
    Since Nullable is a value type, would inherit from struct. Correct? If so, how instructing where T : struct exclude the non-nullable types? Does this make sense? I am sorry but I can't get it.
  • Servy
    Servy over 9 years
    @Christos It doesn't apply to that constraint because that's what the C# language specs say should happen. Note there is no struct type. It is not something that is inherited from. It is a concept; some types satisfy it, and some don't. It's that simple.
  • John Melville
    John Melville almost 5 years
    Please notice the date on this answer, it was true when it was written. In 2019 c# 8.0 adds non-nullable reference types to C#.
  • Guvante
    Guvante about 4 years
    "Generic declarations that include the notnull constraint can be used in a nullable oblivious context, but compiler does not enforce the constraint." So if you aren't compiling with nullable enable it won't do anything.
  • Liero
    Liero over 2 years
    nullable reference types are finally enabled in .NET 6 project templates by default
  • Noman_1
    Noman_1 almost 2 years
    I'm using .Net Core 3.1 with "Nullable: enable" on project build config. This worked for me