如何在单个类中混合可空和不可空 T

nla*_*aak 3 .net c# generics

我正在使用 C# 10 和 VS2022,如果这会影响答案。

我正在尝试编写一个类来包含具有各种约束的参数。基本类型不应为空,某些参数(如默认值)也应为空,而其他一些参数则需要为空(并且我将根据需要检查它们是否为空)。我找不到在课堂上以任何方式混合类型的方法。

我原本以为可以将T定义为notnull然后使用T?具有我想要可为空的任何属性,同时我可以定义类/函数,这样尝试调用代码无法编译。

    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);
Run Code Online (Sandbox Code Playgroud)

如果我在类中通过 VS2022 检查 Set,它会正确显示 Set(T? value_) 作为参数,但如果我检查parameter.Set,它会显示 Set(int value),然后拒绝编译上述用法:

Argument 1: cannot convert from int? to int
Run Code Online (Sandbox Code Playgroud)

我考虑将可为空的属性定义为 T2 并允许其为空,但随后我遇到了无法比较或分配 T 和 T2 的问题,这会达不到目的。

我在这里错过了一些愚蠢的事情还是有其他方法可以实现这一点?

Gur*_*ron 5

既然您在评论中指出:

我的所有用法(如上所述)都是值类型(主要是 int、float、bool)

只需使用struct 通用约束

where T : struct- 类型参数必须是不可为 null 的值类型。有关可为空值类型的信息,请参阅可为空值类型。由于所有值类型都有一个可访问的无参数构造函数,因此struct约束隐含着new()约束,并且不能与new()约束组合。您不能将struct约束与unmanaged约束结合起来。

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

    public void Set(T? value_) 
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

这将允许T?解析为可空值类型,这将使​​其parameter.Set(null);有效。