2012-06-20 18 views
9

Bu basit bir kod vardır:.NET Kovaryans

public interface IReader<out T> 
{ 
    IEnumerable<T> GetData(); 
} 

Bu arayüz T covariant olmalı ve ben bunu şu şekilde kullanıyorum: T kısıt uygulamak

private static Func<bool> MakeSynchroFunc<T>(IReader<T> reader) where T : IComposite 
{ 
    return() => Synchronize(reader); 
} 

Not IComposite. senkronizasyon yöntemi giriş bir IReader<IComposite> alır:

private static bool Synchronize(IReader<IComposite> reader) 
{ 
    // ...... 
} 

derleyici o T kısıtlaması ve iReader kovaryanslarına rağmen IReader<IComposite> için IReader<T> den dönüştüremiyor söylüyor.

Burada yanlış yaptığım bir şey var mı? Derleyici kısıtlamayı doğrulayabilmeli ve kovaryansbenim IReader<Icomposite> kullanmama izin vermeli, değil mi?

Teşekkürler.

+3

Ne yapardın? Sonra varyans kuralları bozulur. Derleyiciyi kimliğini koruyan bir dönüşüm olacağından emin olmak için bir 'class' kısıtlaması gerekir. Bakınız: [C# 4'teki bir kovaryans hatası mı?] (Http://stackoverflow.com/questions/2783233/is-this-a-covariance-bug-in-c-sharp-4) – Ani

+0

evet, sorun, şimdi iyi çalışıyor. –

+0

['covariance neden jenerik yöntemle çalışmıyor]' ın olası kopyası (http://stackoverflow.com/questions/12743444/why-covariance-does-not-work-with-generic-method) – nawfal

cevap

5

T ürününe class kısıtlaması ekleyerek sorununuzu çözebilmeniz gerekir. Yapılar söz konusu olduğunda kovaryans çalışmaz (IEnumerable<int>, IEnumerable<object>'a dönüştürülemez). Bir sınıf olmak için T'u kısıtlamadığınız için, dönüştürülemeyecek olan bir IReader<some struct that implements IComposite> kodunu iletebilirsiniz.

+0

cool, şu an çalışıyor, kovaryansın değer türleri ile çalışmadığını biliyordum ama bunun bu durumda benim sorunumun sebebi olduğunu anlayamadım. sınıf kısıtlaması eklemek, onu mükemmel şekilde çalışır hale getirir. teşekkür ederim !! –

1

Ne yazık ki değil. Jenerikler kovaryant değildir. ve IReader<IComposite>, T'un IComposite ile ilişkili olmasına rağmen, birbirleriyle ilgisiz türlerdir.

EDIT: Neden bunun neden işe yaramayacağını bilmiyorum. Net 4 ve <out T>. Başka biri cevap verebilir mi? Bu gerçekten hiçbir şey istediğini olduğundan

+1

emin misiniz? IReader arabirim tanımındaki dışarıdaki belirteci, derleyiciye, arabirimin eşdeğer olduğunu söylemelidir. .NET 4 –

+3

kullanıyorum Bu yanıt açıklığa kavuşturmak gerekiyor; Yazılı olarak oldukça kafa karıştırıcı. –

+0

Arabirim kovaryansı için anahtar sözcüğünü bilmiyordum ve bunun hakkında okudum, OP'nin kodunun neden çalışmadığını göremiyorum. Bir şey öğrendiğimden beri soru için +1 ve umarım başka biri cevap verebilir. – GazTheDestroyer

0

Neden, fonksiyon tanımını değiştirmez:

private static Func<bool> MakeSynchroFunc<T>(IReader<IComposite> reader) where T : IComposite 

Sen başka şeyler için jenerik parametre T gerekebilir, bu yüzden orada bırakmış.

+0

Çünkü başka bir şey için T parametresine ihtiyacım var, bu gerçek bir kod değil, sadece bir örnekti. ve derleyicinin, açık bir şekilde belirtmek yerine, T türünü çıkarmasına izin vermek istiyorum. –