为什么 Nullable 类型必须有结构约束?

3
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(SomeFunction<int>()==null);
        var temp = new SomeClass<int>();
        Console.WriteLine(temp.SomeFunction() == null);
        Console.ReadKey();
    }

    static public T? SomeFunction<T>() where T : struct
    {
        return null;
    }

    public class SomeClass<T> where T : struct 
    {
        public T? SomeFunction()
        {
            return null;
        }
    }
}

在上述示例中,为什么可空类型需要使用结构约束呢?我不明白为什么要用struct而不是object或class。
3个回答

8

因为 Nullable<T>(或T?)也限制了T必须是一个结构体。

因此,对于SomeFunction<T>的泛型类型参数T来满足Nullable<T>的要求,SomeFunction<T>必须同时声明相同的约束条件。

这里有另一个约束条件必须传播的例子:

interface ISomeInterface { }
class MyClass<T> where T: ISomeInterface { }

class Program
{
    //MyClass's constaints must be "re-declared" here
    public MyClass<T> SomeFunction<T>() where T : ISomeInterface
    {
    }
}

那么为什么Nullable<T>要这样做呢?因为一个可空的引用类型是没有意义的。引用类型本身已经是可空的了。


+1 此外,引用类型已经可为空,并不能证明“为什么结构体是正确的语法”的问题。 - Royi Namir
@RoyiNamir 第一句话已经解释了这个问题。 - dcastro
我认为OP想知道的是:为什么他们首先选择使用结构体来反映可空性... - Royi Namir
1
@RoyiNamir,你是正确的。OP确切地想知道这个问题,但我要说的是,原因是因为规范这样规定的。 - Rahul
@Rahul:“我不明白为什么结构体是正确的语法”,我理解为:“为什么 SomeFunction 必须声明 where T : struct?” Nullable<T> 本身是一个结构体这一事实是无关紧要的,即使 Nullable<T> 是引用类型,你仍然必须添加 where T:struct 约束。 - dcastro
显示剩余3条评论

2

T?Nullable<T> 的缩写,Nullable<T> 要求 T 必须是一个结构体:

public struct Nullable<T> where T : struct

0

Nullable<T> 是一个结构体(参见 MSDN),但它是唯一不满足结构体约束的结构体。另外,当使用类或结构体约束时,您不能将 Nullable 用作泛型类型参数。

Nullable<T> 的基本思想是拥有一个存储位置,可以包含 T 或表示“值缺失”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接