【问题标题】:Why is Nullable type supported by CLR?为什么 CLR 支持 Nullable 类型?
【发布时间】:2011-08-09 11:42:10
【问题描述】:

听说C#2.0增加Nullable<T>类型需要稍微修改一下CLR(runtime),这个改动有必要吗?如果只添加一个新的Nullable<T> 泛型类,它是否可以实现相同的目标?

【问题讨论】:

  • 装箱转换由 CLR 实现。 Nullable 有一个不寻常的装箱转换。因此需要在 CLR 中使用不寻常的代码。
  • @Hans:您知道 CLR 的任何其他领域——与 C# 编译器等相反——其中可空值是特殊情况的吗?我能想到的唯一另一个是where T : struct 通用约束。
  • @Luke - 有很多。最好的办法是在 SSCLI20 clr/src/vm 目录中搜索“可为空”。

标签: c# clr


【解决方案1】:

Nullable 不是您所说的泛型类,Nullable<T> 是泛型的(它有一个类型参数,T)。这就是为什么Nullable<T> 只出现在 C# 2.0 中的原因:它在 CLR 中添加了泛型。

你可以对一般的Nullable 做同样的事情,但你不能这样做:

int? myInt = 123;
int result = myInt.Value;

您将不得不:

int result = (int)myInt.Value;

...它可能不是类型安全的,我的意思是如果myInt.Valuestring 怎么办?通用版本Nullable<T> 只允许int 进入Value 属性。

不过,我不完全明白你在问什么……“为什么泛型类有用”?

【讨论】:

  • 我只是想知道为什么需要更改运行时才能让Nullable<T> 工作。例如,如果我复制其所有定义并将其重命名为Nullable1<T>,是否可以获得与Nullable<int> 相同的行为?
  • 在 C# 2.0 之前,没有泛型 - 所以你不能拥有像 Nullable<T> 这样的泛型类。除非您有其他信息或参考资料?你当然可以创建自己的Nullable1<T>
  • 谢谢。我的意思是在 C# 2.0 或更高版本中添加Nullable1<T>,但它会获得与 CLR 定义的行为相同的行为吗?
  • 不太一样。 CLR 中的 Nullable 是值类型,您将创建的将是引用类型,如果您将其创建为值类型,那么您将无法将其分配给 null 值,因为根据定义,值类型是不可为空的。
  • @Fadrian:您的评论有点误导:这个问题询问了 CLR,而 CLR 不允许 允许您将 null 分配给任何值类型,甚至可以为 null。 C# 编译器确实 允许您将 null 分配给可空对象,但只是在幕后将其转换为值类型的零初始化。 (话虽如此,CLR 中有特定于 nullable 的逻辑。例如,nullables 的装箱和拆箱是特殊情况,where T : struct 泛型约束也是如此。)
【解决方案2】:

如果我理解正确,你问为什么不能只是在框架库中引入类型?但是需要更改 CLR?

根据我的理解,Nullable 是一种特殊类型,与其他容器类型不太一样。首先,它实际上是一个值类型——定义为结构,而不是类。另外,它允许分配一个 null 值(对于值类型,这是一种特殊情况),而且它支持使用 '?'和运算符'??'这是全新的。 Nullable 也成为通用类型系统的一部分。所以我想从这些角度来看,规范、编译器和 CLR 都需要改变。

【讨论】:

  • 是的,你有我的问题。我只是想知道框架库中的纯定义是否可以完成整个工作。
  • 不,请参阅我对 Kieren 回答的评论。
  • @Fadrian:您在此处描述的“技巧”都是由 C# 编译器执行的,而不是 CLR。 (但是,CLR 确实支持具有与装箱/拆箱和通用约束相关的特殊行为的空值。)
【解决方案3】:

我知道对 Nullable 的特殊处理只有两个原因:

  1. 允许从 null 对象引用类型转换到 HasValue = false 的 Nullable
  2. 允许 HasValue 为 false 的 Nullable 比较等于 null。

坦率地说,认为让 Nullable 像任何其他值类型一样框起来会更好,并将 Nullable.Empty 定义为可以比较的值(对于那些可能想要比较的情况)针对可能为 null 或可能包含值的变量)。在我看来,没有理由 Object.Equals 应该报告“int?”哪个等于 null 等于一个“长?”这也等于 null。第一个应该被视为一个空的 int 大小的盒子,而后者应该被视为一个空的 long 大小的盒子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-01
    • 2012-04-25
    • 1970-01-01
    • 2018-04-02
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多