4

我一直认为 .NET 框架的可为空类型只不过是框架为我们提供的一个不错的构造,但并没有为语言本身添加任何新内容。

也就是说,直到今天,出于演示的目的,我尝试创建自己的 Nullable 结构。

我得到了我需要的一切,除了这样做的能力:

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

问题是第二条语句,因为我无论如何都不能重载赋值运算符。

我的问题是:这是赋值运算符重载的语言中的一种特殊情况吗?如果不是,您将如何使前面的示例工作?

谢谢!

4

4 回答 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);
}

可悲的是,有很多与Nullable<T>C# 语言和 CLR相关的功能无法在您的代码中复制

于 2012-05-04T20:16:19.623 回答
5

其他答案同上,但请注意,这Nullable<T>也确实有一些魔力

引用 Lippert 的答案

C# 自动将运算符提升为可为空的。没有办法说“自动将操作员提升到 MyNullable”。不过,您可以通过编写自己的用户定义运算符来非常接近。

C# 对 null 文字有特殊的规则——您可以将它们分配给可为 null 的变量,并将它们与可为 null 的值进行比较,编译器会为它们生成特殊的代码。

可空对象的装箱语义非常奇怪,并且融入了运行时。没有办法模仿他们。

is、as 和合并运算符的可空语义已融入语言。

Nullables 不满足结构约束。没有办法效仿。

等等。

于 2012-05-04T20:20:35.630 回答
3

不是赋值运算符被重载,而是该类Nullable<T>指定了一个隐式转换运算符,该运算符能够转换TNullable<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;
于 2012-05-04T20:15:54.247 回答
1

根据this page运算符重载

请注意,赋值运算符本身 (=) 不能重载。

您可以定义一个 隐式运算符

于 2012-05-04T20:16:17.460 回答