62

C#言語仕様では、セクション§7.5.2で型推論について説明しています。その中には私にはわからない詳細があります。次の場合を考えてみましょう。

// declaration
void Method<T>(T obj, Func<string, T> func);

// call
Method("obj", s => (object) s);

MicrosoftとMonoC#コンパイラはどちらもT=objectを正しく推測しますが、仕様のアルゴリズムを理解するとT=が生成されstring、失敗します。これが私がそれを理解する方法です:

最初のフェーズ

  • Eiが無名関数の場合、EiからTiへの明示的なパラメーター型推論(§7.5.2.7)が行われます。

    ⇒ラムダ式には明示的なパラメータータイプがないため、効果はありません。右?

  • それ以外の場合、EiのタイプがUで、xiが値パラメーターの場合、UからTiへの下限推論が行われます。

    ⇒最初のパラメータは静的タイプなstringので、これはstringの下限に追加されTますよね?

第二段階

  • Xjに依存しない(§7.5.2.5)すべての非固定型変数Xiは固定されています(§7.5.2.10)。

    T固定されていません。T何にも依存していません...だからT修正する必要がありますよね?

§7.5.2.11修正

  • 候補タイプのセットUjは、Xiの境界のセット内のすべてのタイプのセットとして始まります。

    ⇒{ string(下限)}

  • 次に、Xiの各境界を順番に調べます。[...] Xiの各下限Uについて、Uからの暗黙の変換がないすべてのタイプUjが候補セットから削除されます。[...]

    ⇒候補セットから何も削除されませんよね?

  • 残りの候補タイプUjの中に、他のすべての候補タイプへの暗黙の変換がある一意のタイプVがある場合、XiはVに固定されます。

    ⇒候補タイプは1つしかないため、これは空虚な真であり、Xiはに固定されstringます。右?


それで、私はどこで間違っているのですか?

4

1 に答える 1

41

更新:今朝のバスに関する私の最初の調査は不完全で間違っていました。第一段階の仕様のテキストは正しいです。実装は正しいです。

仕様は、第2フェーズでイベントの順序が間違っているという点で間違っています。非依存パラメーターを修正するに、出力型推論を行うことを指定する必要があります。

男、これは複雑です。仕様のこのセクションを、覚えているよりも何度も書き直しました。

私は以前にこの問題を見たことがあり、間違った用語「型変数」がどこでも「型パラメーター」に置き換えられるように修正したことをはっきりと覚えています。(型パラメーターは、内容が変化する可能性のある保管場所ではないため、変数と呼ぶのは意味がありません。)同時に、順序が間違っていることに気づきました。おそらく何が起こったのかというと、誤って古いバージョンの仕様をWebで出荷したことが原因です。多くの謝罪。

Madsと協力して、実装に一致するように仕様を更新します。私は、第二段階の正しい言い回しは次のようになるべきだと思います:

  • 固定されていない型パラメーターが存在しない場合、型推論は成功します。
  • それ以外の場合、対応するパラメータータイプTiを持つ引数Eiが1つ以上存在し、タイプTiの出力タイプに少なくとも1つの非固定タイプパラメーターXjが含まれ、タイプTiの入力タイプのいずれにも非固定タイプパラメーターが含まれない場合Xjの場合、出力タイプの推論は、そのようなすべてのEiからTiに対して行われます。

前のステップで実際に推論が行われたかどうかに関係なく、次のように、少なくとも1つの型パラメーターを修正する必要があります。

  • Xiが固定されていないような1つ以上の型パラメーターXiが存在し、Xiに空でない境界のセットがあり、XiがXjに依存しない場合、そのような各Xiは固定されます。修正操作が失敗すると、型推論は失敗します。
  • それ以外の場合、Xiが固定されていないような1つ以上の型パラメーターXiが存在し、Xiに空でない境界のセットがあり、Xiに依存する型パラメーターXjが少なくとも1つある場合、そのような各Xiは固定されます。修正操作が失敗すると、型推論は失敗します。
  • そうしないと、進行できず、パラメータが固定されていません。型推論は失敗します。

型推論が失敗も成功もしない場合、2番目のフェーズが繰り返されます。

ここでの考え方は、アルゴリズムが無限ループにならないようにすることです。第2フェーズが繰り返されるたびに、成功、失敗、または進行します。型に修正する型パラメータがあるよりも多くの回数ループすることはできません。

これを私の注意を引いてくれてありがとう。

于 2010-09-13T14:23:48.793 に答える