??
操做符叫作 null-coalescing operator,即 null 合并运算符。若是此运算符的左操做数不为 null,则此运算符将返回左操做数;不然返回右操做数。html
在微软的官方 C# 文档中,此操做符被定义为不可重载。不过咱们有方法能够间接实现这样的重载。express
你能够阅读 C# 中那些能够被重载的操做符,以及使用它们的那些丧心病狂的语法糖 了解 C# 中提供的全部能够重载的操做符。在此文中,??
被明肯定义为不可重载。编程
你更能够在微软官方文档中找到这样的说法:ide
=, ., ?:, ??, ->, =>, f(x), as, checked, unchecked, default, delegate, is, new, sizeof, typeof
These operators cannot be overloaded.
这些运算符没法进行重载。函数
咱们先写一个空壳子。连构造函数都是 private
的,这个类固然几乎不可用啦。post
特别注意,咱们的 Walterlv.NullableString
用的是 struct
类型,这样能与 Nullable<T>
的用法上接近。也就是说,咱们能够确保其值实际上永不为 null。ui
namespace Walterlv { public struct NullableString { private readonly string _value; private NullableString(string value) { _value = value; } } }
namespace Walterlv { public struct NullableString { private readonly string _value; private NullableString(string value) { _value = value; } } }
如今咱们挑战一下官方说好了不能重载的 ??
重载(做死):spa
![试着重载 ??]](https://img-blog.csdn.net/20180926211208502?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1dQd2FsdGVy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
▲ 试着重载 ??.net
很明显,既不是可重载的一员运算符也不是可重载的二元运算符。code
如今咱们试试隐式转换:
public static implicit operator NullableString(string value) { return new NullableString(value); } public static implicit operator string(NullableString nullableString) { return nullableString._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; }
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; }
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; } } }
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();
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();
NullableString? value = null; var value0 = value?.ToString(); var value1 = value.ToString();
同样的,value0
获得 null
,而 value1
获得 ""
。
另外,你能够从 null
强转出你须要的类:
var value = (NullableString?) null;
var value = (NullableString?) null;