C#泛型類型推論:理解其限制
在使用C#泛型方法時,通常假設編譯器可以根據限制推斷泛型參數。然而,存在一種情況,這種推斷似乎難以實現。
考慮以下程式碼:
<code class="language-csharp">interface IQuery<TResult> { } interface IQueryProcessor { TResult Process<TQuery, TResult>(TQuery query) where TQuery : IQuery<TResult>; } class SomeQuery : IQuery<string> { } class Test { void Test(IQueryProcessor p) { var query = new SomeQuery(); // 编译失败 p.Process(query); // 需要显式指定泛型参数 p.Process<SomeQuery, string>(query); } }</code>
這段程式碼無法編譯,因為無法推斷泛型參數。問題是:為什麼編譯器無法推導出正確的型別?
根據前微軟C#首席工程師Eric Lippert的解釋,原因在於C#執行型別推論的方式。推論僅透過檢查參數和對應的形式參數類型來進行。在本例中,編譯器缺乏足夠的資訊來推斷泛型參數。
約束,例如where TQuery : IQuery<TResult>
定義的約束,不被視為簽名的一部分,因此不能直接用於推論。
為了解決這個問題,必須明確指定泛型參數,如第二個Process
方法呼叫所示。這符合C#的設計理念,即約束提供了附加信息,但不改變方法的簽名。
在最新的C#版本中,應用約束的規則略有修改。為了獲得最準確的信息,建議查閱官方C#文件或檢查C# 7.3以上版本的實際實現。
以上是為什麼 C# 無法推論帶有約束的方法中的泛型類型?的詳細內容。更多資訊請關注PHP中文網其他相關文章!