2016-04-01 9 views
0

Ben üzerinde çalıştığım bir sarmalayıcı üzerinde güzel bir API sağlamak için çalışıyorum ve ben aşağıdaki sorun karşılaştık:Bir görev türünü, bir ifadede belirtmeden genel tür olarak bulmak mümkün müdür?

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); 
    } 
} 

kullanıyorum: Bu benim Sandbox kodu

olduğunu böyle kodu:

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)); 

temelde ben bekliyorum TImplicit birYöntem için int olmalı ve SomeOtherMethod için isteğe Görev (opsiyonel bir imkansız ise ancak benim için mükemmel mantıklı olacağını) için.

+1

BazıExpressionFromTask TImplicit (İfade >> ifade) 'sizin için çalışır mı? Görev türü için gerçekten bir genel parametreye mi ihtiyacınız var? – CodesInChaos

+0

Hayır, aslında bir şeye ihtiyacım yok. Luaan, yapmadan kısa bir süre önce bana bir cevap gönderdi. Çözümünüz de doğruydu. Bunu bir cevap olarak göndermediğinden, ben de seni ödüllendirdim. Teşekkürler. – Dbl

cevap

1

Hayır, pek değil. Bununla birlikte, bir şeyleri fazlasıyla karıştırıyorsunuz demektir. Yerine TWrap: Task<TImplicit> arasında, sadece Task doğrudan kullanın:

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

Eğer tip argümanlar ve kısıtlamaları jenerik kolaylaştıramayız nerede, sadece tür kesmesi için kukla argümanları eklemek için mantıklı olabilir:

public V DoStuff<T, U, V>(Func<T, U> func, V dummy) where U: A<V> { ... } 
hiçbir nokta bunu yaparken de var - sen elbette

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

olabilmesinin önünü

, bu gerçekten sadece bir yardımcı yöntemdir çekirdek uygulamanızda.

+0

Ek yorumun için teşekkürler. Hatırlıyorum, bir dahaki sefere doğru ifadeyi bulmaya çalışıyorum. – Dbl

İlgili konular