方法組自然類型優化
注意
本文是功能規格。 規格可作為功能的設計檔。 其中包含建議的規格變更,以及功能設計和開發期間所需的資訊。 這些文章會發佈,直到提議的規格變更完成並併併入目前的ECMA規格為止。
功能規格與已完成實作之間可能有一些差異。 這些差異在相關的 語言設計會議(LDM)記錄中反映出來。
冠軍問題:https://github.com/dotnet/csharplang/issues/7429
總結
此提案以幾種方式精簡方法群組的自然類型判斷:
- 請依次考慮候選方法的範圍(先考慮實例方法,再依序考慮每個範圍的擴充方法)。
- 修剪沒有成功機會的候選項目,使其不會干擾確定獨特的簽名。
- 未提供類型自變數時修剪泛型實例方法 (
var x = M;
) - 根據能夠減少擴充和條件約束來修剪泛型擴充方法
- 未提供類型自變數時修剪泛型實例方法 (
方法組的自然類型內容
在 C# 10 中,方法群組獲得了弱式自然類型。
該類型是一種「弱型別」,因為它只有在方法群組不是目標型別時才會生效(即它在 System.Action a = MethodGroup;
中沒有作用)。
這種脆弱的自然類型允許出現像 var x = MethodGroup;
這樣的情況。
如果方法群組中的所有候選方法都有通用簽章,則方法群組具有自然類型。 (如果方法群組可能包含擴充方法,則候選專案會包含包含類型和所有擴充方法範圍。
實際上,這表示我們:
- 建構所有候選方法的集合:
- 如果相關型別是靜態的,而且接收者是型別,或是非靜態,而接收者是值,則相關型別上的方法會位於集合中
- 在所有範圍內可縮減的擴充方法都在集合中
- 如果所有候選項目的簽章不相符,則方法群組沒有自然類型
- 如果產生的簽章的參數數目不符合提供的型別參數數目,則方法群組沒有本質型別。
- 否則,產生的簽章會作為自然類型使用
建議
原則是逐個範圍地檢視並及早剔除我們知道不會成功的候選者(這是多載解析中所使用的相同原則)。
- 針對每個範圍,我們會建構所有候選方法的集合:
- zh-TW: 若為初始範圍,則相關型別的方法若與所提供的型別自變數的元數相符且滿足條件限制,則當方法為靜態且接收者為型別時,會包含在集合中;或當方法為非靜態且接收者為值時,也會包含在集合中。
- 針對後續範圍,該範圍中的擴充方法必須可以以提供的型別參數替代,並在使用接收者的值進行簡化的同時滿足約束條件,這樣的方法將列入集合中。
- 若在指定範圍中沒有候選人,請繼續進行下一個範圍。
- 如果所有候選人的簽名不相符,則方法組沒有自然類型
- 否則,生成的簽章會作為預設類型使用
- 如果範圍已用盡,則方法群組沒有自然類型
與逐一範圍提案相關:https://github.com/dotnet/csharplang/issues/7364 與提案相關,以改進處理泛型擴充方法:https://github.com/dotnet/roslyn/issues/69222