可空类型和赋值运算符

Posted

技术标签:

【中文标题】可空类型和赋值运算符【英文标题】:Nullable types and assignment operator 【发布时间】:2012-05-14 09:27:01 【问题描述】:

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

也就是说,直到今天,为了演示,我都尝试创建自己的 Nullable 结构。

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

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

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

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

谢谢!

【问题讨论】:

【参考方案1】:

使用声明为的隐式运算符处理赋值问题:

public static implicit operator Nullable&lt;T&gt; (T value)

这是在没有任何特定语言功能的情况下处理的。

对可空支持的语言的主要更改是能够将其编写为:

 int? myInt = 1;

您可以通过以下方式在您的类型中实现此功能:

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

    return new Nullable<T>(value);

很遗憾,有很多与 C# 语言 Nullable&lt;T&gt; 相关的功能,而 CLR 做到了 can't be duplicated in your code。

【讨论】:

好答案。此外,CLR 还支持将值为 null 的 nullable 装箱到 null 引用。【参考方案2】:

其他答案同上,但请注意Nullable&lt;T&gt; 也确实有一些magic。

引用 Lippert 的回答

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

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

nullables 的装箱语义非常奇怪,并融入了 运行。没有办法模仿它们。

is、as 和合并运算符的可空语义已烘焙 在语言中。

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

等等。

【讨论】:

【参考方案3】:

不是赋值运算符重载,而是Nullable&lt;T&gt; 类指定了一个隐式转换运算符,它能够将T 转换为Nullable&lt;T&gt;

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

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;

【讨论】:

【参考方案4】:

据此页面Operator overloading

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

你可以定义一个implicit operator

【讨论】:

以上是关于可空类型和赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章

赋值运算符的返回类型是啥?

C# 8小特性

c++中为啥赋值运算符重载返回类型是引用

Fortran 派生类型:重载赋值运算符不适用于“参数”属性

在C语言中赋值运算符有啥作用?

拷贝控制——拷贝赋值与销毁