簡體   English   中英

當我期望它選擇非泛型方法時,方法重載選擇泛型方法

[英]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()約束,則通用重載是更好的選擇,因為如果TBaseClassBDerivedClassA1 ,則它比非通用Method(DerivedClassA1)更接近( Method(DerivedClassA1)Method(BaseClassA) )。 但是隨后,它檢查了約束,並發現DerivedClassA1不繼承BaseClassB ,這會導致錯誤。

換句話說,在檢查泛型約束之前,已經消除了非泛型過載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM