Home > front end >  How can I mix nullable and not nullable T within a single class
How can I mix nullable and not nullable T within a single class

Time:06-04

I'm using C# 10 and VS2022, if that affects answers.

I'm trying to write a class to contain parameters with various constraints. The base type should be not nullable, as should some of the parameters (like default) while some of the other parameters need to be nullable (and I'll check they're not null as necessary). I can't find a way to mix the types in any fashion in the class.

I originally thought I could define T as notnull and then use T? with any properties I want nullable, while I can define the class/functions that way trying to call the code fails to compile.

    public class Parameter<T> where T : notnull {
        public T Value { get; set;}
        public T? Min { get; set; }

        public void Set(T? value_) 
        {
        }
    }

Parameter<int> parameter = new();
parameter.Set(null);

If I inspect Set via VS2022 in the class, it properly shows Set(T? value_) as the parameter, but if I inspect parameter.Set it shows Set(int value), and then refuses to compile the above usage with:

Argument 1: cannot convert from int? to int

I considered defining nullable properties as T2 and allowing that to be null, but then I have the issue that I can't compare or assign T and T2, which would defeat the purpose.

Am I missing something stupid here or is there another way to accomplish this?

CodePudding user response:

Since you stated in the comments:

All of my usage (as implied above) will be value types (int, float, bool primarily)

Just use struct generic constraint:

where T : struct - The type argument must be a non-nullable value type. For information about nullable value types, see Nullable value types. Because all value types have an accessible parameterless constructor, the struct constraint implies the new() constraint and can't be combined with the new() constraint. You can't combine the struct constraint with the unmanaged constraint.

public class Parameter<T> where T : struct {
    public T Value { get; set;}
    public T? Min { get; set; }

    public void Set(T? value_) 
    {
    }
}

Which will allow T? to be resolved into nullable value type which will make parameter.Set(null); valid.

  • Related