[英]How to make sure the explicit operator throws the exception when converting null? (not nullable)
我在MyVO
類上有一個顯式運算符,它應該是不可為空的。
public class MyVO : ValueObject<MyVO>
{
public string Value { get; } // Should never be null
private MyVO(string v) => Value = v;
public static explicit operator MyVO(string vo)
{
if (string.IsNullOrWhiteSpace(vo)) throw new Exception('...');
return new MyVO(vo);
}
但是, (MyVO)null
不會引發異常。 該方法的主體將不會運行。
var myVO = (MyVO)null; // myVO will have the null value
如何確保它不為空?
如何確保它不為空?
“它”我假設您的意思是“從null
到MyVO
”。 如果這不是您的意思,請澄清問題。
你不能。
C# 的一個重要規則是用戶定義的轉換在與內置轉換沖突時永遠不會“獲勝” 。 將null
轉換為任何類類型都是合法的,因此MyVO
對表達式null
的MyVO
將始終導致 null 引用。 如果內置轉換有效,編譯器甚至不會考慮用戶定義的轉換。 (相信我;我寫了那個代碼!)
正如 D Stanley 的回答正確指出的那樣,如果null
是string
類型的任何表達式的值,則調用用戶定義的轉換; 沒有從string
到MyVO
內置轉換,因此編譯器會查找適用的用戶定義轉換並找到一個。
因為當你做你正在做的事情時會很痛,你應該停止做你正在做的事情。 顯式轉換可能不是實現所需行為的正確方法。
我想我的問題應該是如何使
MyVO
不可為空。
升級到 C# 8。C# 8 支持對引用類型進行不可為空的注釋。
請注意,不可為空的注釋應該被正確地視為annotation 。 類型系統不保證用不可為空的注釋注釋的變量的值永遠不會被觀察到為空。 相反,它會盡最大努力在代碼看起來有誤時向您發出警告。
在我們查看您的代碼時,我注意到您正在使用ValueObject<T>
,我假設您是從類似的東西中獲得的
https://enterprisecraftsmanship.com/posts/value-object-better-implementation/
讓我借此機會提醒您,使用這種模式存在缺陷; 您認為或希望被應用於約束T
不是適用於約束T
。 我們經常看到這樣的事情:
abstract class V<T> where T : V<T>
{
public void M(T t) { ... } // M must take an instance of its own type
}
如果我們有class Banana : V<Banana>
那么Banana.M
將一個Banana
作為它的參數,這就是我們想要的。 但是現在假設我們有class Giraffe : V<Banana>
。 在這種情況下, Giraffe.M
不帶長頸鹿; 它需要一根香蕉,盡管Giraffe
與Banana
根本沒有關系。
約束並不意味着M
始終把自己的類的實例。 如果您嘗試在 C# 中使用這種約束構造泛型類型,則不能; C# 類型系統不夠豐富,無法表達該約束。
null
可以隱式轉換為任何引用類型,因此編譯器不會使用您的顯式轉換運算符。 嘗試
string s = null;
o = (MyVO)s;
或者只是內聯它
o = (MyVO)((string)s);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.