2016-04-01 7 views
0

私に働いていると私は次の問題に遭遇してきたラッパーの上に素敵なAPIを提供しようとしている:タスクのタイプを式で指定することなく汎用タイプとして推論することはできますか?

これは私のサンドボックスコードです:

public interface ISomeInterface 
{ 
    Task<int> SomeMethod(int i); 
    Task<Task<int>> SomeOtherMethod(int i); 
} 

public class TestClass<TSource> 
{ 
    public TWrap ReturnExpressionAsIs<TWrap>(Expression<Func<TSource, TWrap>> expression) 
    { 
     return default(TWrap); 
    } 

    public TImplicit SomeExpressionFromTask<TWrap, TImplicit>(Expression<Func<TSource, TWrap>> expression) where TWrap : Task<TImplicit> 
    { 
     return default(TImplicit); 
    } 
} 

私が使用しています

var testProxy = new TestClass<ISomeInterface>(); 
// Task<int> - working as intended 
var ordinaryTypeInfer = testProxy.ReturnExpressionAsIs(d => d.SomeMethod(5)); 

// int - working as intended 
var expressionExplicit = testProxy.SomeExpressionFromTask<Task<int>, int>(d => d.SomeMethod(5)); 

// compiler error - shouldn't this be possible through type inference? 
var expressionImplicitAttempt = testProxy.SomeExpressionFromTask(d => d.SomeMethod(5)); 

は基本的に私は(オプション1は私のために完璧な理にかなっていることは不可能であるしかし場合)TImplicitはSomeOtherMethodためのsomeMethodのためのint型と、必要に応じてタスクであることを期待しています。このようなコード。

+1

TImplicit SomeExpressionFromTask (式 >>式)はあなたのために機能しますか?あなたは本当にタスクタイプのためのジェネリックパラメータが必要ですか? – CodesInChaos

+0

いいえ、私は実際には必要ありません。 Luaanはあなたの直前に答えを出し、それを私に指摘しました。あなたのソリューションは確かに正しいものでした。あなたは答えとして投稿していないので、私もあなたに報酬を与えました。ありがとう。 – Dbl

答えて

1

いいえ、実際はありません。

しかし、あなたは物事を複雑にしています。代わりにTWrap: Task<TImplicit>の、ちょうど直接Taskを使用します。

public TImplicit SomeExpressionFromTask<TSource, TImplicit> 
     (Expression<Func<TSource, Task<TImplicit>>> expression) 
{ 
    return default(TImplicit); 
} 

場合、あなたはジェネリック型引数と制約を簡素化することができない場合には、それだけで型推論のためのダミー引数を追加しても意味があり:

public V DoStuff<T, U, V>(Func<T, U> func, V dummy) where U: A<V> { ... } 

あなたはもちろん

DoStuff(i => SomeFun(i), default(int)); 

を呼び出すことができますどの、これは本当にただのヘルパーメソッドである - それを行うにはポイントはありませんあなたのコア実装では

+0

あなたのコメントをお寄せいただきありがとうございます。次回は、私が正しい表現を思いつくために苦労していることを覚えておいてください。 – Dbl

関連する問題