【问题标题】:Why string or object type don't support nullable reference type? [duplicate]为什么字符串或对象类型不支持可为空的引用类型? [复制]
【发布时间】:2014-01-20 11:34:11
【问题描述】:

查看以下代码块:

//Declaring nullable variables.
//Valid for int, char, long...
Nullable<int> _intVar;
Nullable<char> _charVar;

//trying to declare nullable string/object variables
//gives compile time error. 
Nullable<string> _stringVar;
Nullable<object> _objVar;

编译代码时编译器给出以下错误信息:

类型“字符串”/“对象”必须是不可为空的值类型,才能在泛型类型或方法“System.Nullable”中用作参数“T”

看了好几遍还是没看懂。任何人都可以澄清这一点吗?为什么objectstring 不支持可空引用类型?

【问题讨论】:

  • 因为yiu可以直接赋值null:String value = null;对象 o = null;相反,你不能用结构来做到这一点,例如整数=空;是编译时错误
  • 因为它们已经可以为空了? string _stringVar = null; 编译正常。
  • 例如你不能连接空字符串
  • @WeylandYutani:这是什么意思,它有什么相关性?
  • @WeylandYutani 是的,你可以;结果定义明确(就连接而言,所有null 字符串的行为与"" 相同)

标签: c# nullable


【解决方案1】:

objectstring 是引用类型,因此它们已经可以为空。例如,这已经是有效的:

string x = null;

Nullable&lt;T&gt; 泛型类型仅适用于 T 是不可为空的 类型的情况。

Nullable&lt;T&gt; 的声明中,T 有一个约束:

public struct Nullable<T> where T : struct

where T : struct 正是将T 限制为不可为空的值类型的部分。

【讨论】:

  • 并且约束可能是为了确保您不会做任何太疯狂的事情。 .NET 进行了大量优化,以确保使用 Nullable 不会对性能造成重大影响。毕竟,Nullable 本身就是一个值类型(一个结构),但你不能做一个可空的可空 - 编译器可能在 C# 泛型约束未涵盖的地方有一个额外的验证 - 只需使用 Nullable 的反编译代码就会让你做一个例如。 MyNullable&lt;MyNullable&lt;int&gt;&gt;.
  • @Luaan:不,这里没有“额外验证”:where T : struct 已经阻止了Nullable&lt;Nullable&lt;int&gt;&gt;,因为Nullable&lt;int&gt; 不是不可为空的值类型。我怀疑你的反编译版本没有包含约束。
  • @Luaan 专门针对Nullable&lt;T&gt; 案例的“额外验证” - where T : struct 明确有相关规则,不适用于MyNullable&lt;T&gt; / MyNullable&lt;MyNullable&lt;T&gt;&gt; - 但它阻止MyNullable&lt;Nullable&lt;T&gt;&gt;
  • 约束在那里。签名是public struct Nullable&lt;T&gt; where T : struct,即。它也是一个结构,因此也是一个有效的值类型。我的逻辑/理解有什么问题?
  • @Luaan:您假设where T : struct 意味着T 只需要是一个结构。它必须是 non-nullable 值类型。 Nullable&lt;int&gt; 不是不可为空的值类型。但是是的,考虑一下,您的 MyNullable&lt;T&gt; 不会被视为可空值类型,因此 MyNullable&lt;MyNullable&lt;int&gt;&gt;Nullable&lt;MyNullable&lt;int&gt;&gt; 都可以,但 MyNullable&lt;Nullable&lt;int&gt;&gt; 不会。
【解决方案2】:

Nullable&lt;T&gt; 定义为:

public struct Nullable<T> where T : struct

含义:它只适用于值类型T(不包括Nullable&lt;TSomethingElse&gt;本身)。

你不能在引用类型(或Nullable&lt;T&gt;)上使用Nullable&lt;T&gt;,但你不需要因为所有引用类型(包括objectstring)已经是“可空的”,在您可以将null 分配给他们。

【讨论】:

    【解决方案3】:

    字符串和对象引用类型,因此已经是“可空的”。 Nullable&lt;T&gt; 类型作为 值类型 的包装器存在,不支持开箱即用的 null

    string myString = null //fine
    int myInt = null //compiler error
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 2015-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多