[英]Method overload selecting generic method when I was expecting it to select non-generic method
采取以下代碼:
class BaseClassA { }
class DerivedClassA1 : BaseClassA { }
class BaseClassB { }
class DerivedClassB1 : BaseClassB { }
static class Operations
{
public static BaseClassA Method(BaseClassA baseA)
{
//...
return baseA;
}
public static TBaseClassB Method<TBaseClassB>(TBaseClassB baseB)
where TBaseClassB : BaseClassB, new()
{
//...
return baseB;
}
class Program
{
static void Main(string[] args)
{
BaseClassA baseA = new BaseClassA();
DerivedClassA1 derivedA1 = new DerivedClassA1();
DerivedClassB1 derivedB1 = new DerivedClassB1();
baseA = Operations.Method(baseA);
derivedA1 = Operations.Method(derivedA1); // Compilation error
derivedB1 = Operations.Method(derivedB1);
}
}
}
標記為// Compilation error
的行將導致以下錯誤:
The type 'DerivedClassA1' cannot be used as type parameter
'TBaseClassB' in the generic type or method
'Operations.Method<TBaseClassB>(TBaseClassB)'.
There is no implicit reference conversion from 'DerivedClassA1'
to 'BaseClassB'.
當給定類型為DerivedClassA1
的參數時,方法重載似乎是選擇Operations.Method<TBaseClassB>(TBaseClassB)
方法重載,而不是Operations.Method(BaseClassA)
,這與我的預期相反。 為什么是這樣? 難道我做錯了什么? 有沒有一種替代/正確的方法來實現我想要的,那就是調用Method(BaseClassA)
方法重載。
請注意,示例代碼是我正在處理的某些實際代碼的簡化等效項。 抱歉,如果該示例看起來人為。
重載解析不會考慮泛型約束,因為這些約束實際上並不是方法簽名的一部分(您不能在只有泛型約束不同的同一類中創建相同的方法)。 解析算法首先選擇最佳候選者,然后才檢查它是否驗證約束。
在您的情況下,如果忽略where TBaseClassB : BaseClassB, new()
約束,則通用重載是更好的選擇,因為如果TBaseClassB
是DerivedClassA1
,則它比非通用Method(DerivedClassA1)
更接近( Method(DerivedClassA1)
比Method(BaseClassA)
)。 但是隨后,它檢查了約束,並發現DerivedClassA1
不繼承BaseClassB
,這會導致錯誤。
換句話說,在檢查泛型約束之前,已經消除了非泛型過載。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.