2017-09-27 79 views
6

yok sayar.Jenerik kısıt en biz <code>T</code> içinde <em>eş varyant</em> olduğunu</p> <pre><code>public interface IEnumerable<out T> { /*...*/ } </code></pre> <p>gibi bir arabirim var diyelim eş varyans

public interface ISomeInterface {} 
public class SomeClass : ISomeInterface 
{} 

Şimdi eş-varyans bize Yani bir IEnumerable<SomeClass>bir değişkene atanabilir aşağıdaki

IEnumerable<ISomeInterface> e = Enumerable.Empty<SomeClass>(); 

yapmanızı sağlar:

Sonra başka arayüzü ve bir sınıf uygulamadan var IEnumerable<ISomeInterface> türünde (veya yöntem parametresi). Biz genel bir yöntemde bu denerseniz

Ama:

public void GenericMethod<T>(IEnumerable<T> p) where T : ISomeInterface 
{ 
    IEnumerable<ISomeInterface> e = p; 
    // or 
    TestMethod(p); 
} 
public void TestMethod(IEnumerable<ISomeInterface> x) {} 

biz IEnumerable<T> bir IEnumerable<ISomeInterface> dönüştürülebilir edilemeyeceğini bize söylemeden derleyici hatası CS0266 olsun.

kısıtlama açıkça TISomeInterface türetilmiştir ifade eder ve IEnumerable<T> yana (yukarıda gösterildiği gibi), bu atama çalışması gerekir T eş-varyantıdır.

Bunun genel bir yöntemde çalışamaması için teknik bir neden var mı? Ya da özlediğim herhangi bir şey derleyicinin bunu anlamasını çok pahalı kılıyor mu?

cevap

5
sizin GenericMethod değiştirin ve eklemek jenerik kısıtlamasını class

:

public void GenericMethod<T>(IEnumerable<T> p) where T : class, ISomeInterface 
{ 
    IEnumerable<ISomeInterface> e = p; 
    // or 
    TestMethod(p); 
} 

Covariance does not support structs, bu yüzden biz sadece sınıfları kullanmak istediğinizi söylemek gerekir.

+1

Oh, bana onu döv. Şimdi bir kaç gün önce bu yapı/varyans problemi hakkında bir şeyler okuduğumu hatırlıyorum. Hızlı yanıt için teşekkürler. –

+0

@ RenéVogt yardımcı olmaktan memnun – Backs