2009-07-30 13 views
6

ジェネリック型を推論するためにC#コンパイラを取得するには?

次のメソッドがあります:

public TResult Get<TGenericType, TResult>() 
          where TGenericType : SomeGenericType<TResult> 
          where TResult : IConvertible { 
    //...code that uses TGenericType... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

このメソッドのユーザーは、このように使用する必要があります。

//Notice the duplicate int type specification 
int number = Get<SomeGenericType<int>, int>(); 

なぜメソッド定義にTResultを指定する必要がありますか?コンパイラはTGenericTypeで指定してから既にTResultを知っています。理想的には(C#コンパイラが少しスマートだった場合)、私の方法は次のようになります:

public TResult Get<TGenericType>() 
          where TGenericType : SomeGenericType<TResult> 
          where TResult : IConvertible { 
    //...code that uses TGenericType... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

したがって、ユーザーは単純に次のように使用できます:

//Much cleaner 
int number = Get<SomeGenericType<int>>(); 

私がやりたいこと?

+0

質問の説明から* stupid *などの修飾語を削除すると効果があります。 – EFraim

+0

これは愚かなコンパイラですよね? ;)私は余分な解説を取り除いた。これは実際にはそれがなければ妥当な質問です。 –

+0

タイプパラメータの一部だけを使用する方法がないと答えたので、おそらくあなたは達成したいことに関して質問を再定式化するべきでしょう。 C#言語の定義に違反するコードをコンパイルするにはどうすればいいですか?したがって、それは「本当の質問ではない」として閉じられるべきです。 –

答えて

8

C#仕様では、型引数の半分を推論することはできません。コンパイラにすべての型引数(あなたの場合のようにいつも適用可能ではない)を推論させるか、またはそれらのすべてを手動で指定する必要があります。

私はC#チームであなたの質問に絶対的な答えをしているわけではありませんが、私の推測では、過負荷解決の複雑さ(既に心が吹き荒れています; C#仕様のそのセクションを読んだ場合)は、型の半分が推定され、半分は許容されないようにするためには大幅に増加します(特に、汎用引数の数だけメソッドをオーバーロードできるという事実を考慮して)。

+0

しかし、なぜ彼らはC#の仕様でそれを指定しましたか?それはそれについて不安な何かのようではありません。 –

+0

テンプレートの部分的な特殊化やアクセス指定子の働きなど、C++ルールのいくつかを調べてください。通常、物事はスムーズに機能しますが、ここには暗闇が潜んでいます。 JavaとC#の背後にあるアイデアの1つは、C++の複雑さを避けることだったので、ちょっとした不便さを受け入れることになりました。 –

1

それが依存...

あなただけSomeGenericType<TResult>を使用している場合は、行うことができます:

public TResult Get<TResult>() where TResult : IConvertible { 
    SomeGenericType<TResult> myInstance = ... 
    //...code that sets someValue... 
    return (TResult) someValue; 
} 

が、必ずしもこのような場合には、そこに最初のタイプを配置する方法はありません。あなたの例は明示的にパラメータとしてSomeGenericType<TResult>を渡さないので、これが可能であることを示唆しています。

それ以外の場合は、すべての汎用引数を完全に指定する必要があります。残念ながら、これはC#でのやり方です。

+0

確かに、メソッドでSomeGenericType を使用する必要があります。わかりやすくするためにサンプルコードを更新します。 –

+0

ええ、私のコードを見てください - メソッドのパラメータとして渡されない限り、メソッド内でSomeGenericType を使用することができます(つまり、メソッド内にSomeGenericTypeを構築する場合)。あなたはTResultを知っているので、これはうまく動作します。私が言ったように、それはいくつかのケースで動作することができます... –

+0

申し訳ありませんが、私はTGenericType(私の更新されたサンプルコードを参照してください)を使用する必要があることを意味します。 –

関連する問題