C#中煩人的Null值判斷竟然這樣就被消滅了
阿新 • • 發佈:2020-12-25
> 作者:依樂祝
> 首發自:DotNetCore實戰 公眾號
> https://www.cnblogs.com/yilezhu/p/14177595.html
Null值檢查應該算是開發中最常見且煩人的工作了吧,有人反對嗎?反對的話請右上角關門不送。這篇文章就教大家一招來簡化這個煩人又不可避免的工作。
> 說明,提供思路的一篇文章招來這麼多非議,為何啊?
羅嗦話不多說,先看下面一段簡單的不能再簡單的null值判斷程式碼:
```csharp
public void DoSomething(string message)
{
if(message == null)
throw new ArgumentNullException();
// ...
}
```
方法體的每個引數都將用if語句進行檢查,並逐個丟擲 `ArgumentNullException` 的異常。
關注我的朋友,應該看過我上篇《[一個小技巧助您減少if語句的狀態判斷](https://www.cnblogs.com/yilezhu/p/14174990.html)》的文章,它也是簡化Null值判斷的一種方式。簡化後可以如下所示:
```csharp
public void DoSomething(string message)
{
Assert.That(message == null, nameof(DoSomething));
// ...
}
```
但是還是很差強人意。
![](https://cdn.nlark.com/yuque/0/2020/jpeg/266699/1608693683209-4ad2d9c1-979f-4a09-aee2-ea41f1e93ab4.jpeg#align=left&display=inline&height=333&margin=%5Bobject%20Object%5D&originHeight=333&originWidth=500&size=0&status=done&style=none&width=500)
**
### NotNullAttribute
這裡你可能想到了 `_System.Diagnostics.CodeAnalysis_` 名稱空間下的這個 [NotNull] 特性。這不會在執行時檢查任何內容。它只適用於CodeAnalysis,並在編譯時而不是在執行時發出警告或錯誤!
```csharp
public void DoSomething([NotNull]string message) // Does not affect anything at runtime.
{
}
public void AnotherMethod()
{
DoSomething(null); // MsBuild doesn't allow to build.
string parameter = null;
DoSomething(parameter); // MsBuild allows build. But nothing happend at runtime.
}
```
### 自定義解決方案
這裡我們將去掉用於Null檢查的if語句。如何處理csharp中方法引數的賦值?答案是你不能!. 但你可以使用另一種方法來處理隱式運算子的賦值。讓我們建立 `NotNull` 類並定義一個隱式運算子,然後我們可以處理賦值。
```csharp
public class NotNull
{
public NotNull(T value)
{
this.Value = value;
}
public T Value { get; set; }
public static implicit operator NotNull(T value)
{
if (value == null)
throw new ArgumentNullException();
return new NotNull(value);
}
}
```
現在我們可以使用NotNull物件作為方法引數.
```csharp
static void Main(string[] args)
{
DoSomething("Hello World!"); // Works perfectly