C#編譯器歧義呼叫錯誤:方法群組與委託類型
在C#中,當使用方法組語法呼叫具有多個重載的函數時,編譯器可能會遇到「歧義呼叫」錯誤。此錯誤發生是因為當存在兩個具有相容委託類型的方法群組時,編譯器無法確定要呼叫哪個重載。
考慮以下程式碼範例:
<code class="language-csharp">public class ClassWithDelegateMethods { public void Method(Func<string> func) { /* do something */ } public void Method(Action action) { /* do something */ } } public class ClassWithSimpleMethods { public string GetString() { return ""; } public void DoNothing() { } } public class Program { public static void Main(string[] args) { // 错误:歧义调用 ClassWithDelegateMethods classWithDelegateMethods = new ClassWithDelegateMethods(); classWithDelegateMethods.Method(classWithSimpleMethods.GetString); // 这里会报错 classWithDelegateMethods.Method(classWithSimpleMethods.DoNothing); // 这里会报错 } }</code>
ClassWithDelegateMethods.Method
的兩個重載都可以使用匿名方法或lambda表達式呼叫而不會出現任何問題。但是,使用方法組語法呼叫 classWithSimpleMethods.GetString
或 classWithSimpleMethods.DoNothing
會導致歧義錯誤。
此錯誤的原因在於方法群組和委託類型之間的隱式轉換規則。根據C#規範,方法組到相容委託類型之間存在隱式轉換。但是,對於具有重載的方法組,規範沒有定義確定要轉換為哪個重載的機制。
避免歧義錯誤
為了解決歧義錯誤,可以將方法群組明確轉換為所需的委託類型。例如:
<code class="language-csharp">// 无错误 classWithDelegateMethods.Method((Func<string>)classWithSimpleMethods.GetString); classWithDelegateMethods.Method((Action)classWithSimpleMethods.DoNothing);</code>
或者,從C# 7.3開始,編譯器改進的重載候選選擇演算法消除了此問題。因此,在C# 7.3及更高版本中,上面的程式碼範例應該可以編譯而無需明確轉換。
以上是為什麼 C# 在使用具有重載委託方法的方法群組時會引發「不明確的呼叫」錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!