メソッド グループ自然型の改善
手記
この記事は機能仕様です。 仕様は、機能の設計ドキュメントとして機能します。 これには、提案された仕様の変更と、機能の設計と開発時に必要な情報が含まれます。 これらの記事は、提案された仕様の変更が最終決定され、現在の ECMA 仕様に組み込まれるまで公開されます。
機能の仕様と完成した実装の間には、いくつかの違いがある可能性があります。 これらの違いは、関連する 言語設計会議 (LDM) ノートでキャプチャされます。
機能仕様を C# 言語標準に導入するプロセスの詳細については、仕様に関する記事を参照してください。
チャンピオンの課題: https://github.com/dotnet/csharplang/issues/7429
概要
この提案では、メソッド グループの自然な型の決定をいくつかの方法で絞り込みます。
- スコープごとの候補メソッドを検討する (最初にインスタンス メソッド、次に各スコープ、その後に拡張メソッドのスコープ)
- 成功する可能性がない候補者を排除し、一意の署名の決定に干渉しないようにします。
- 型引数が指定されていない場合にジェネリック インスタンス メソッドを排除する (
var x = M;
) - 拡張を削減できることと制約に基づいて、ジェネリック拡張メソッドを削除する。
- 型引数が指定されていない場合にジェネリック インスタンス メソッドを排除する (
メソッド グループの自然型に関するコンテキスト
C# 10 では、メソッド グループは弱い自然型を得ました。
この型は、メソッド グループがターゲット型でない場合にのみ実行されるという点で "弱い型" です (つまり、System.Action a = MethodGroup;
で役割を果たしません)。
その弱い自然型は、var x = MethodGroup;
のようなシナリオを可能にします.
メソッド グループ内のすべての候補メソッドに共通のシグネチャがある場合、メソッド グループには自然な型があります。 (メソッド グループに拡張メソッドが含まれている可能性がある場合、候補には、含まれる型とすべての拡張メソッド スコープが含まれます)。
実際には、これは次のことを意味します。
- すべての候補メソッドのセットを構築します。
- 関連する型のメソッドは、静的で受信側が型の場合、または非静的で受信側が値である場合、セット内に存在します。
- 削減できる拡張メソッド (すべてのスコープにわたって) はセット内にあります。
- すべての候補のシグネチャが一致しない場合、メソッド グループには自然な型がありません
- 結果のシグネチャのアリティが指定された型引数の数と一致しない場合、メソッド グループには自然な型がありません
- それ以外の場合、結果のシグネチャは自然な型として使用されます
建議
原則は、スコープごとに移動し、できるだけ早く成功できないことがわかっている候補を排除することです (オーバーロード解決で使用されるのと同じ原則)。
- スコープごとに、すべての候補メソッドのセットを構築します。
- 初期スコープにおいて、関連する型のメソッドで、指定された型引数と一致するアリティを持ち、かつその型引数に対する制約を満たすものは、受信側が型で静的な場合または受信側が値で非静的な場合にセットに含まれます。
- 後続のスコープの場合、指定された型引数に置き換え、条件を満たしながら受信側の値を使用して削減できる、そのスコープ内の拡張メソッドがセット内にあります
- 指定されたスコープに候補がない場合は、次のスコープに進みます。
- すべての候補のシグネチャが一致しない場合、メソッド グループには自然な型がありません
- それ以外の場合は、結果のシグネチャが自然な型として使用されます
- スコープが使い果たされた場合、メソッド グループには自然な型がありません
スコープごとの提案に関連する: https://github.com/dotnet/csharplang/issues/7364 汎用拡張メソッドをより適切に処理するための提案に関連: https://github.com/dotnet/roslyn/issues/69222
C# feature specifications