C#关于参数为null(空值)的方法调用,重载顺序选择彻底研究
其實這是一個很老的問題了,很久以前就在園子里看到有人對此迷惑,當時也沒太在意,覺得哪會有人那么寫代碼。直到最近丁學君的這篇文章:“關于參數為可空值類型的多個重載的優先級”才讓我對這個問題重新有了興趣。并且做出了一個大膽的猜想,現在這個猜想已經被我驗證了。
?
所有具備單向隱式類型轉換或者存在繼承關系的類型的方法重載,當使用null值調用時,將會使用隱式類型轉換的方向來確定調用哪個方法。
?
簡而言之,假設TypeA和TypeB之間存在一個隱式類型轉換或者繼承關系,方向是TypeA對象可以隱式轉換為TypeB(TypeA存在一個到TypeB的隱式類型轉換或者TypeA派生于TypeB)。
又有兩個方法的重載如下:
public void MyMethod( TypeA obj ){ … }//重載A
public void MyMethod( TypeB obj ){ … }//重載B
?
那么MyMethod( null )一定會選擇重載A。
?
但是這還沒完,我仔細測定了各種情況的調用情況,并和裝配腦袋一起分析整理了一下,還有如下結論:
?
1、對于Nullable<T>類型而言,T所擁有的運算符(包括隱式類型轉換運算符)都會被投射到T?類型。比如說,int有一個隱式類型轉換到long,那么int?也就會自動存在一個隱式類型轉換到long?。同樣的,TypeA?也有一個隱式類型轉換到TypeB?(如果TypeA和TypeB是值類型)。這就解釋了丁學文章中所說的問題。
?
2、如果兩個類型之間存在雙向的隱式類型轉換,即TypeA可以隱式類型轉換為TypeB,而TypeB也可以隱式類型轉換為TypeA,這種情況下,使用null值調用會是一個編譯錯誤。推廣開來,如果多個類型之間存在一個閉環的隱式類型轉換,比如說TypeA->TypeB,TypeB->TypeC,TypeC->TypeA,那么如果這三個類型的重載都存在的話,使用null值調用同樣的編譯錯誤,但是如果只有兩個類型的重載存在(即方法重載的參數類型不存在閉環)那么也不會有錯誤。
?
3、數組的協變也會被看作是一個隱式類型轉換,比如說TypeA派生于TypeB,則TypeA[]存在一個到TypeB[]的隱式轉換,這個被稱之為數組的協變。那么這個隱式轉換也會被這個規則采信,即如果兩個方法的參數是TypeA[]和TypeB[]的話,采用null值調用會選擇TypeA[]的重載。
?
4、VB中也采用類似的規則,這一點有待裝配腦袋的確認。
總結
以上是生活随笔為你收集整理的C#关于参数为null(空值)的方法调用,重载顺序选择彻底研究的全部內容,希望文章能夠幫你解決所遇到的問題。