2016-01-29 19 views
12

Komple uzatma yöntemi alıcı gibi soru kabul değildir:Neden (T) IEnumerable kodundan önce

Neden IEnumerable<T>where T : ITestthis IEnumerable<ITest> beklediği bir uzantısı yönteminin alıcı olarak kabul edilmez?

Ve şimdi kod:

Ben üç tip var:

public interface ITest { } 
public class Element : ITest { } 
public class ElementInfo : ITest { } 

Ve iki uzatma yöntemleri:

public static class Extensions 
{ 
    public static IEnumerable<ElementInfo> Method<T>(
     this IEnumerable<T> collection) 
     where T : ITest 
    { 
→  return collection.ToInfoObjects(); 
    } 

    public static IEnumerable<ElementInfo> ToInfoObjects(
     this IEnumerable<ITest> collection) 
    { 
     return collection.Select(item => new ElementInfo()); 
    } 
} 

(işaretli satırda) alıyorum derleyici hatası :

CS1929: 'IEnumerable<T>''ToInfoObjects' için bir tanım ve en uzantısı yöntemi aşırı 'Extensions.ToInfoObjects(IEnumerable<ITest>)' içermez neden bu kadar olan tipte 'IEnumerable<ITest>'

bir alıcısı gerektirir? ToInfoObjects uzantı yönteminin alıcısı bir IEnumerable<T> ve jenerik tip kısıtlaması ile TITest'u uygulamalıdır.

Neden alıcı kabul edilmiyor? Benim tahminim IEnumerable<T>'un kovaryansıdır ama emin değilim.

'u IEnumerable<T> where T : ITest almak için değiştirirseniz, her şey yolundadır.

cevap

13

bu düşünün. MethodTclass kısıtı eklerseniz, kodunuz derlenecek.

+0

Gerçekten iyi bir cevap. Saygı. – Vasilievski

+0

Şimdi bunu söyledin, benim için açık görünüyor. T değeri olabilirdi ve tabii ki işe yaramazdı. Çok teşekkür ederim. Bir takip olarak, [nedenine bağlantı] yapmak istiyorum (http://stackoverflow.com/questions/12454794/why-covariance-and-contravariance-do-not-support-value-type) neden co (ntra)) Varyans, değer tipleri ile çalışmaz. –

-1

Aşağıdaki yapabilirsiniz:

public static IEnumerable<ElementInfo> Method<T>(
     this IEnumerable<T> collection) 
     where T : ITest 
    { 
     return collection.ToInfoObjects(); 
    } 

    public static IEnumerable<ElementInfo> ToInfoObjects<T>(
     this IEnumerable<T> collection) 
    { 
     return collection.Select(item => new ElementInfo()); 
    } 

Bildirimi ToInfoObjects üzerinde.

public struct ValueElement : ITest { } 

ve bu:

IEnumerable<ValueElement> collection = ... 
collection.Method(); //OK, ValueElement implement ITest, as required. 
collection.ToInfoObjects() //Error, IEnumerable<ValueElement> is not IEnumerable<ITest> 
          //variance does not work with value types. 

Yani Method için izin verilen her tür de ToInfoObjects için izin verilmez

+0

Öneriniz için teşekkürler, ancak sorunu çözmek için neler yapabileceğimi biliyorum ve dahası, orijinal yazıya yazdım. İstediğim şey sorunun nasıl çözüleceğini değil, nasıl çözüleceğini bilmek. –

+0

@KornelijePetak Sorunuza yeterince dikkat etmediğiniz için üzgünüm. –

İlgili konular