2016-10-31 10 views
3

は、次の例を考えてみましょう:タイプ推論は右から左に行われますか?

この2行は、仕事とうまく実行
public class Person 
{ 
    public int Age { get; set; } 
} 

public class Builder<TSource> 
{ 
    public Builder<TSource> WithValue<TValue>(Func<TSource, TValue>, TValue value) 
    { 
     // ... 
    } 
} 

Builder<Person> builder = new Builder<Person>(); 
builder.WithValue(p => p.Age, 20); 

をしかしので、これらの操作を行います。

Builder<Person> builder = new Builder<Person>(); 
object age = "20";        // <-- string value 
builder.WithValue(p => p.Age, age); 

型推論が道Iが動作しません後者の例で動作することを期待してください。

式(Func<Person, int>)を指定すると、2番目の引数がintタイプに制限されていると考えられます。しかし、私はobjectをうまく通すことができます。

これは、タイプ推論が右から左に行われているためです。つまり、TValue引数がobjectと推測されていて、次にFunc<TSource, TValue>式がFunc<Person, object>に制約されています。p => p.Ageはそれほど問題ありません。

私の前提は正しいですか?

もしそうなら、なぜこのように型推論が行われますか?私はそれが左から右へもっと自然であると感じます。

答えて

5

注文には一切依存しません。パラメータp => p.Ageには、TValueのいずれかがintを格納できるタイプでなければならないという制約が追加されています。それはintまたはそれが継承する任意のタイプ(たとえば、object)です。 ageを渡すと、TValueobjectを格納できるタイプでなければならないと言っています。次に、すべての制約を満たす最も派生した型を選択します。この場合はobjectです。パラメータの順序を変更した場合も同じことが起こります。

+0

最も派生型がint型ではありませんか? –

+0

@MatiasCicero 'int'型は両方の制約を満たすわけではありません。 'int'型の変数に' object'を格納することはできないので、2つの制約のうちの1つを満たしています。 – Servy

+0

私は今それを得ると思います。迅速な答えをありがとう! –

1

左から右にも右から左にもありません。型推論は、与えられた状況で利用可能な型情報を取り、置換可能な型を調べて、それぞれの式と互換性があるようにしようとします。これは通常、最も近い共通の祖先によって満たされます。あなたのケースでは、intobjectは、この最も近い共通の祖先としてobjectを持っています。しかし、一般に、解像度のために解像度が少し複雑になることがあります。

関連する問題