内容简介:在微软的官方 C# 文档中,此操作符被定义为不可重载。不过我们有方法可以间接实现这样的重载。你可以阅读
??
操作符叫做 null-coalescing operator,即 null 合并运算符。如果此运算符的左操作数不为 null,则此运算符将返回左操作数;否则返回右操作数。
在微软的官方 C# 文档中,此操作符被定义为不可重载。不过我们有方法可以间接实现这样的重载。
运算符重载
你可以阅读 C# 中那些可以被重载的操作符,以及使用它们的那些丧心病狂的语法糖 了解 C# 中提供的所有可以重载的操作符。在此文中, ??
被明确定义为不可重载。
你更可以在微软官方文档中找到这样的说法:
=, ., ?:, ??, ->, =>, f(x), as, checked, unchecked, default, delegate, is, new, sizeof, typeof
These operators cannot be overloaded.
这些运算符无法进行重载。
编写 NullableString 的 ?? 重载
我们先写一个空壳子。连构造函数都是 private
的,这个类当然几乎不可用啦。
特别注意,我们的 Walterlv.NullableString
用的是 struct
类型,这样能与 Nullable<T>
的用法上接近。也就是说,我们可以确保其值实际上永不为 null。
namespace Walterlv { public struct NullableString { private readonly string _value; private NullableString(string value) { _value = value; } } }
现在我们挑战一下官方说好了不能重载的 ??
重载(作死):
▲ 试着重载 ??
很明显,既不是可重载的一员运算符也不是可重载的二元运算符。
现在我们试试隐式转换:
public static implicit operator NullableString(string value) { return new NullableString(value); } public static implicit operator string(NullableString nullableString) { return nullableString._value; }
然而这样的写法实际上并无实际用途。
但是,我们可以在 NullableString
后面加上 ?
:
public static implicit operator NullableString?(string value) { return string.IsNullOrEmpty(value) ? (NullableString?) null : new NullableString(value); } public static implicit operator string(NullableString? nullableString) { return nullableString?.ToString() ?? string.Empty; }
也就是说,C# 竟然允许隐式转换的时候,参数和返回值都不是此类型。当然,实际上这只对 Nullable<T>
生效,如果你试图写别的类型,是不可以的。
为了方便,我们重写一下 ToString()
,部分场景下可以代替隐式转换,少写一些代码。
public override string ToString() { return string.IsNullOrEmpty(_value) ? string.Empty : _value; }
于是,我们的 NullableString
类型的完整代码如下:
namespace Walterlv { public readonly struct NullableString { private readonly string _value; private NullableString(string value) { _value = value; } public static implicit operator NullableString?(string value) { return string.IsNullOrEmpty(value) ? (NullableString?) null : new NullableString(value); } public static implicit operator string(NullableString? nullableString) { return nullableString?.ToString() ?? string.Empty; } public override string ToString() { return string.IsNullOrEmpty(_value) ? string.Empty : _value; } } }
注释就你自己添加吧。
一些注意事项
这里有一些好玩的事情需要分享。比如我们写出如下代码:
NullableString? value = ""; var value0 = value?.ToString(); var value1 = value.ToString();
你觉得 value0
和 value1
分别会得到什么呢?
呃……
value0
得到 null
,而 value1
得到 ""
。
另外,如果你将一开始的初始值设为 null
,那又可以得到什么结果呢?
NullableString? value = null; var value0 = value?.ToString(); var value1 = value.ToString();
一样的, value0
得到 null
,而 value1
得到 ""
。
另外,你可以从 null
强转出你需要的类:
var value = (NullableString?) null;
本文会经常更新,请阅读原文: https://walterlv.com/post/overload-null-coalescing-operator-in-csharp.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接:https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com) 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Kotlin Vocabulary:操作符重载
- C# 中那些可以被重载的操作符,以及使用它们的那些丧心病狂的语法糖
- Android RxJava 操作符详解系列:条件 / 布尔操作符
- C语言中点操作符(.)和箭头操作符(->)的不同之处
- JavaScript骚操作之操作符
- JS操作符拾遗
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Node即学即用
[英] Tom Hughes-Croucher、[英] Mike Wilson / 郑达韡 / 人民邮电出版社 / 2013-2 / 39.00元
《Node即学即用》由休斯-克劳奇、威尔逊编著,《Node即学即用》讲解如何用Node构建可扩展因特网应用,是全面的实用指南,除了详细介绍Node提供的API外,还用大量篇幅介绍了服务器事件驱动开发的重要概念。内容涉及跨服务器的并发连接、非阻塞I/O和事件驱动的编程、如何支持各种数据库和数据存储工具、NodeAPI的使用示例等。适合对JavaScript及编程有一定程度了解的读者阅读。一起来看看 《Node即学即用》 这本书的介绍吧!