問題の理解C#言語仕様で説明されているように推論をタイプ
-
02-10-2019 - |
質問
C#言語仕様 セクション§7.5.2のタイプ推論について説明します。私が理解していない詳細があります。次のケースを検討してください。
// declaration
void Method<T>(T obj, Func<string, T> func);
// call
Method("obj", s => (object) s);
MicrosoftとMono C#コンパイラの両方が正しく推測します T
= object
, 、しかし、仕様におけるアルゴリズムの私の理解は得られます T
= string
そして、失敗します。これが私がそれを理解する方法です:
最初のフェーズ
EIが匿名関数の場合、an 明示的なパラメータータイプ推論 (§7.5.2.7)は、EIからTiに作られています
ラムダ式には明示的なパラメータータイプがないため、効果はありません。右?
それ以外の場合、EIにタイプuがあり、xiが値パラメーターである場合、 下部の推論 uからtiに作られています。
⇒最初のパラメーターは静的タイプです
string
, 、これが追加されますstring
下限にT
, 、 右?
第2フェーズ
全て 固定されていません 変数xiを型にしません による (§7.5.2.5)xjは固定されています(§7.5.2.10)。
⇒
T
固定されていません。T
何にも依存しない...だからT
修正する必要がありますよね?
§7.5.2.11固定
候補タイプUJのセットは、XIの境界セットのすべてのタイプのセットとして始まります。
⇒ {
string
(下限)}次に、XIの各バウンドを順番に調べます。 [...
⇒候補者セットから何も削除しませんよね?
残りの候補タイプUJの中に、他のすべての候補タイプへの暗黙的な変換がある一意のタイプVがある場合、XIはVに固定されます。
⇒候補者タイプは1つしかないので、これは空虚ですので、xiは
string
. 。右?
それで、私はどこに間違っているのでしょうか?
解決
更新:今朝のバスでの私の最初の調査は不完全で間違っていました。第1フェーズ仕様のテキストは正しいです。実装は正しいです。
スペックは、第2フェーズでイベントの順序が間違っているという点で間違っています。出力タイプの推論を行うことを指定する必要があります 前 非依存パラメーターを修正します。
男、このようなものは複雑です。私は覚えているよりも多くの時間をスペックのこのセクションを書き直しました。
私は以前にこの問題を見たことがありますが、誤った用語「タイプ変数」が「タイプパラメーター」とどこにでも置き換えられたように、改訂を行ったことを明確に思い出します。 (タイプパラメーターは、内容が異なる可能性のあるストレージの場所ではないため、変数を呼び出すことは意味がありません。)同時に、順序が間違っていたと思いました。おそらく起こったのは、Webに古いバージョンのスペックを誤って出荷したことでした。多くの謝罪。
MADSと協力して、実装に合わせて仕様を更新します。第2フェーズの正しい言葉遣いは次のようになるはずだと思います:
- 固定されていないタイプパラメーターが存在しない場合、タイプ推論が成功します。
- それ以外の場合は、タイプTIを持つ出力タイプのEIが少なくとも1つの固定型パラメーターXJを含むように、対応するパラメータータイプTIを持つ1つ以上の引数EIが存在する場合、タイプTIを持つEIの入力タイプは、固定タイプパラメーターを含むものはありません。 XJ、次に、そのようなすべてのEIからTIから出力型推論が作成されます。
以前のステップが実際に推論したかどうかにかかわらず、次のように、少なくとも1つのタイプパラメーターを修正する必要があります。
- xiが固定されていないように1つ以上のタイプパラメーターxiが存在し、xiが空でない一連の境界を持ち、xiがxjに依存しない場合、そのようなxiはそれぞれ固定されます。修正操作が失敗した場合、タイプの推論が失敗します。
- それ以外の場合、xiが固定されていないように1つ以上のタイプパラメーターxiが存在する場合、xiには空白のない境界セットがあり、xiに依存する少なくとも1つのタイプパラメーターXJがあり、そのようなxiはそれぞれ固定されます。修正操作が失敗した場合、タイプの推論が失敗します。
- それ以外の場合、進歩を遂げることができず、固定されていないパラメーターがあります。タイプの推論が失敗します。
タイプの推論が失敗したり成功したりしない場合、第2フェーズが繰り返されます。
ここでのアイデアは、アルゴリズムが無限のループにならないようにしたいということです。第2フェーズの繰り返しごとに、成功、失敗、または進行します。タイプを修正するタイプパラメーターがあるよりも多くの回数ループできないでしょう。
これを私の注意を喚起してくれてありがとう。