可空类型和赋值运算符

4

我一直认为.NET框架中的可空类型只是一个好的构造,是框架给我们提供的,而并没有添加任何新的语言功能。

直到今天,出于演示目的,我尝试创建自己的Nullable结构体,我得到了所有我需要的东西,除了能够做到这一点:

var myInt = new Nullable<int>(1);
myInt = 1;

问题出在第二个语句,因为无论如何我都不能重载赋值运算符。
我的问题是:在这种语言中是否有特殊情况,即赋值运算符有一个重载?如果没有,你会如何解决之前的例子?
谢谢!
4个回答

10

这个任务使用一个被声明为隐式运算符的方式来处理:

public static implicit operator Nullable<T> (T value)

这是在不使用任何特定于语言的功能的情况下进行处理的。

支持可空类型的语言的主要变化是可以将其写成以下形式:

 int? myInt = 1;

您可以通过以下方式在您的类型中实现此功能:
public static implicit operator Nullable<T> (T value)
{
    return new Nullable<T>(value);
}

话虽如此,与C#语言和CLR相关的Nullable<T>有许多功能是您的代码无法复制的。


2
好的回答。此外,CLR 支持将一个具有 null 值的可空类型装箱为一个 null 引用。 - usr

5
同其他答案一样,但请注意Nullable<T>也会进行一些魔法
引用Lippert的回答:
C#自动将运算符提升为可空类型。 没有办法说“自动将运算符提升为MyNullable”。 但是,您可以通过编写自己的用户定义运算符来实现非常接近的效果。
C#有特殊规则来处理null字面量-您可以将它们分配给可空变量,并将它们与可空值进行比较,编译器会为它们生成特殊代码。
可空类型的装箱语义非常奇怪,并且已经嵌入到运行时中。 没有办法模拟它们。
is、as和合并运算符的可空类型语义已经嵌入到语言中。
可空类型不满足结构体约束。 没有办法模拟它。

3

并非重载赋值运算符,而是类Nullable<T>指定了一种隐式转换运算符,可以将T转换为Nullable<T>

您可以轻松地将此功能添加到您的类中:

class MyInteger {
  private int value;

  public MyInteger(int value) { this.value = value; }

  public static implicit operator MyInteger(int value) {
    return new MyInteger(value);
  }
}

然后以相同的方式使用运算符:

MyInteger obj = 123;

1

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