??
操做符叫作 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;