做者:依樂祝
首發自:DotNetCore實戰 公衆號
https://www.cnblogs.com/yilezhu/p/14177595.htmlhtml
Null值檢查應該算是開發中最多見且煩人的工做了吧,有人反對嗎?反對的話請右上角關門不送。這篇文章就教你們一招來簡化這個煩人又不可避免的工做。app
說明,提供思路的一篇文章招來這麼多非議,爲什麼啊?ui
羅嗦話很少說,先看下面一段簡單的不能再簡單的null值判斷代碼:this
public void DoSomething(string message) { if(message == null) throw new ArgumentNullException(); // ... }
方法體的每一個參數都將用if語句進行檢查,並逐個拋出 ArgumentNullException
的異常。
關注個人朋友,應該看過我上篇《一個小技巧助您減小if語句的狀態判斷》的文章,它也是簡化Null值判斷的一種方式。簡化後能夠以下所示:code
public void DoSomething(string message) { Assert.That<ArgumentNullException>(message == null, nameof(DoSomething)); // ... }
可是仍是不好強人意。
**htm
這裏你可能想到了 _System.Diagnostics.CodeAnalysis_
命名空間下的這個 [NotNull] 特性。這不會在運行時檢查任何內容。它只適用於CodeAnalysis,並在編譯時而不是在運行時發出警告或錯誤!對象
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<T>
類並定義一個隱式運算符,而後咱們能夠處理賦值。blog
public class NotNull<T> { public NotNull(T value) { this.Value = value; } public T Value { get; set; } public static implicit operator NotNull<T>(T value) { if (value == null) throw new ArgumentNullException(); return new NotNull<T>(value); } }
如今咱們可使用NotNull對象做爲方法參數.ci
static void Main(string[] args) { DoSomething("Hello World!"); // Works perfectly 👌 DoSomething(null); // Throws ArgumentNullException at runtime. string parameter = null; DoSomething(parameter); // Throws ArgumentNullException at runtime. } public static void DoSomething(NotNull<string> message) // <--- NotNull is used here { Console.WriteLine(message.Value); }
如您所見, DoSomething()
方法的代碼比之前更簡潔。也能夠將NotNull類與任何類型一塊兒使用,以下所示:開發
public void DoSomething(NotNull<string> message, NotNull<int> id, NotNull<Product> product) { // ... }
感謝您的閱讀,咱們下篇文章見~
參考自:https://enisn.medium.com/never-null-check-again-in-c-bd5aae27a48e