【问题标题】:Why cant I declare a generic list as nullable?为什么我不能将通用列表声明为可为空的?
【发布时间】:2011-09-14 15:18:01
【问题描述】:

我正在尝试使用以下代码:

private Nullable<List<IpAddressRange>> ipAddressRangeToBind;

但我收到以下警告:

List 类型必须是不可为空的值类型 为了将它用作泛型类型或方法中的参数“T” 'System.Nullable'。

【问题讨论】:

    标签: c# null nullable


    【解决方案1】:

    List&lt;T&gt; 已经是一个引用类型(对于任何类型的T)——你只能声明Nullable&lt;T&gt;,其中T 是一个不可为空的值类型(它被声明为Nullable&lt;T&gt; where T : struct)。

    不过没关系,因为如果你只是声明:

    private List<IpAddressRange> ipAddressRangeToBind;
    

    那么你还可以拥有

    ipAddressRangeToBind = null;
    

    因为引用类型总是可以为空。

    【讨论】:

      【解决方案2】:

      List&lt;IpAddressRange&gt; 是一个引用类型 - 它已经可以为空 - 实际上它会被该声明初始化为 null。

      【讨论】:

        【解决方案3】:

        你可以直接使用它:

        List<IpAddressRange> ipAddressRangeToBind = null;  
        

        列表已经可以为空。

        【讨论】:

        • 是真的,为什么我不能这样做,虽然出于兴趣...?
        • 我猜是因为正如 Jon Skeet 解释的那样,约束 Nullable&lt;T&gt; where T : structIpAddressRange 不是 struct。为什么你问的约束?这是一个不同的问题:)
        • @Pete2k:我添加了一个关于为什么不存在约束的答案。这不是第一个答案,所以我不想为答案声称功劳,但只是发表评论太长了......
        【解决方案4】:

        由于泛型的where T : struct 约束,引用类型不能包装在Nullable&lt;T&gt; 中。

        这个限制的原因是:

        1. 根据定义,引用类型已经可以为空,并且
        2. Nullable 不是很节省空间,但更多的是“逻辑”可空性。

        Nullable&lt;T&gt; 有一个布尔属性HasValue 和一个类型T 属性Value,其中包含实际的值类型值。

        即使HasValue == false(也就是说,如果可以为空的包装变量设置为null),您仍然会消耗值类型的空间,就好像它在那里一样。

        逻辑上可以为空以允许您指定可选行为,但它不会节省任何空间。这与 boost::optional 在 C++ 中的工作方式非常相似。

        【讨论】:

        • 我现在知道 Where 子句是什么了!
        • Nullable&lt;T&gt; 的许多烦恼源于希望让它假装一个空实例是null。恕我直言,这是一个不幸的决定,因为它阻止了像 TryGetValue 这样可能有也可能没有 T 返回的方法,而不必担心 TValue 的类型而无需担心 TValue 的类型(如果 @返回项的987654335@为false,key不存在;HasValue为true,即使存储的Value恰好是null,key也存在。另一方面,虽然可空类型在逻辑上应该与其类型参数协变......
        • ...(因为任何Animal? 都应该能够保存任何Cat? 的内容),使协方差在从Animal?Animal??Object 的转换中起作用保留可空性的程度,将要求从可空类型转换为 Object 不使用正常装箱。在正常的装箱规则下,装箱的值类型总是是可变的(即使底层的值类型被认为是“不可变的”)。太糟糕了,因为这样的设计增加了使诸如“可读字典”接口之类的东西与存储在其中的值的类型相关的难度。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-17
        • 1970-01-01
        • 2011-03-29
        • 1970-01-01
        • 2011-01-23
        相关资源
        最近更新 更多