我一直认为 .NET 框架的可为空类型只不过是框架为我们提供的一个不错的构造,但并没有为语言本身添加任何新内容。
也就是说,直到今天,出于演示的目的,我尝试创建自己的 Nullable 结构。
我得到了我需要的一切,除了这样做的能力:
var myInt = new Nullable<int>(1);
myInt = 1;
问题是第二条语句,因为我无论如何都不能重载赋值运算符。
我的问题是:这是赋值运算符重载的语言中的一种特殊情况吗?如果不是,您将如何使前面的示例工作?
谢谢!
我一直认为 .NET 框架的可为空类型只不过是框架为我们提供的一个不错的构造,但并没有为语言本身添加任何新内容。
也就是说,直到今天,出于演示的目的,我尝试创建自己的 Nullable 结构。
我得到了我需要的一切,除了这样做的能力:
var myInt = new Nullable<int>(1);
myInt = 1;
问题是第二条语句,因为我无论如何都不能重载赋值运算符。
我的问题是:这是赋值运算符重载的语言中的一种特殊情况吗?如果不是,您将如何使前面的示例工作?
谢谢!
分配问题是使用声明为的隐式运算符处理的:
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相关的功能无法在您的代码中复制。
其他答案同上,但请注意,这Nullable<T>也确实有一些魔力。
引用 Lippert 的答案
C# 自动将运算符提升为可为空的。没有办法说“自动将操作员提升到 MyNullable”。不过,您可以通过编写自己的用户定义运算符来非常接近。
C# 对 null 文字有特殊的规则——您可以将它们分配给可为 null 的变量,并将它们与可为 null 的值进行比较,编译器会为它们生成特殊的代码。
可空对象的装箱语义非常奇怪,并且融入了运行时。没有办法模仿他们。
is、as 和合并运算符的可空语义已融入语言。
Nullables 不满足结构约束。没有办法效仿。
等等。
不是赋值运算符被重载,而是该类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;