C#編譯器歧義呼叫錯誤:匿名方法與方法群組
C# 提供兩種呼叫函數的語法:匿名方法(或 lambda 語法)和方法群組。當一個函數有多個重載,接受不同的委託類型時,使用方法組語法可能會出現歧義。
考慮以下程式碼範例:
<code class="language-csharp">class Program { public static void Main() { // 匿名方法(编译成功) Method(() => classWithSimpleMethods.GetString()); Method(() => classWithSimpleMethods.DoNothing()); // 使用显式转换的方法组(也编译成功) Method((Func<string>)classWithSimpleMethods.GetString); Method((Action)classWithSimpleMethods.DoNothing); // 方法组(错误:“歧义调用”) Method(classWithSimpleMethods.GetString); Method(classWithSimpleMethods.DoNothing); } public static void Method(Func<string> func) { /* 执行某些操作 */ } public static void Method(Action action) { /* 执行某些操作 */ } }</code>
在這個例子中,Method
函數有兩個重載,一個接受 Action
,另一個接受 Func<string>
。當使用匿名方法或明確轉換為正確的委託類型呼叫函數時,程式碼可以編譯而不會出錯。但是,當使用方法組語法時,編譯器會報告“歧義呼叫”錯誤。
理解歧義
C# 語言規範指出,從方法群組到相容的委託類型存在隱式轉換。但是,在這種情況下,編譯器面臨歧義,因為方法群組 classWithSimpleMethods.GetString
可以隱式轉換為 Func<string>
和 Action
。
根據規範,重載解析涉及根據匹配的參數類型選擇最適用的候選者。雖然 GetString
方法的參數清單與兩個重載都相容,但編譯器無法確定最佳匹配,因為它在重載解析期間不考慮返回類型。
解歧義
為了解決歧義,可以使用明確轉換為正確的委託類型,如程式碼範例所示。但是,這種方法可能很繁瑣且容易出錯。
幸運的是,在 C# 7.3 及更高版本中,編譯器已經改進以處理這種情況。現在,根據與目標委託類型的兼容性對重載候選者進行排名,從而在這種情況下無需明確轉換。
以上是為什麼 C# 在使用方法群組而不是匿名方法時會拋出「不明確的呼叫」錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!