2010-05-20 17 views
12

निम्नलिखित कोड (VS2010 का प्रयोग करके) को संकलित करने में विफल रहता है लागू कर रहा है और मैं क्यों नहीं दिख रहा है विफल रहता है। संकलक अनुमान लगाने के लिए कि List<TestClass> 'संगत' IEnumerable<ITest> साथ (एक बेहतर शब्द की कमी के लिए खेद है) में सक्षम होना चाहिए, लेकिन किसी भी तरह यह नहीं है। मुझे यहां क्या समझ नहीं आ रहा है?सी # संकलक पहचान करने के लिए एक वर्ग एक अंतरफलक


interface ITest { 
    void Test(); 
} 


class TestClass : ITest { 
    public void Test() { 
    } 
} 

class Program { 
    static void Test(IEnumerable<ITest> tests) { 
     foreach(var t in tests) { 
      Console.WriteLine(t); 
     } 
    } 
    static void Main(string[] args) { 
     var lst = new List<TestClass>(); 

     Test(lst); // fails, why? 

     Test(lst.Select(t=>t as ITest)); //success 

     Test(lst.ToArray()); // success 
    } 
} 

संकलक दो त्रुटियों देता है:

  1. 'ConsoleApplication1.Program.Test (System.Collections.Generic.IEnumerable < ConsoleApplication2 लिए अच्छी अतिभारित विधि मैच .ITest >) 'में कुछ ऐसी अमान्य तर्क हैं

  2. तर्क 1: 'System.Collections.Generic.List <ConsoleApplication2.TestClass>' से परिवर्तित नहीं कर सकते 'System.Collections.Generic.IEnumerable <ConsoleApplication2.ITest>'

उत्तर

8

जो आप करने की कोशिश कर रहे हैं उसे covariance कहा जाता है - एक संक्षिप्त प्रकार (टेस्ट क्लास) से व्यापक प्रकार (ITest) में परिवर्तित किया जाता है। यह ऐसा कुछ है जिसे आप हर समय इस्तेमाल करेंगे, ऐसा तब होता है जब आप फ्लोट से दो बार उदाहरण में बदल जाते हैं।

दुर्भाग्य से नेट 3.5 और कम सामान्य कक्षाओं में सहप्रसरण का समर्थन नहीं करता।

नेट 4.0 अब जेनरिक में सहप्रसरण (और contravariance) का समर्थन करता है, उन सामान्य कक्षाओं covariant प्रकार के लिए out और in contravarient प्रकार के लिए कीवर्ड के साथ संकलित किया गया है प्रदान की है। .NET 4.0 में IEnumerable को कॉन्वेंट के रूप में परिभाषित किया गया है। आप सही IEnumerable प्रकार पर क्लिक करें और क्लिक करें "गोटो परिभाषा", तो आप इस देखेंगे:

public interface IEnumerable<out T> : IEnumerable 

आप VS2010 का उपयोग कर रहे हैं, तो आप अपनी परियोजना के .net 4.0 लक्षित कर रहा है सुनिश्चित करने के लिए की आवश्यकता होगी। इसे परियोजना गुणों से बदला जा सकता है। प्रोजेक्ट पर राइट क्लिक करें, गुणों का चयन करें, "एप्लिकेशन" टैब प्राप्त करें और जांचें कि "लक्ष्य ढांचा" .Net 4.

MSDN has more information पर है।

2

यह करना पड़ता है करने के लिए भिन्नता के साथ करें (covariance और contravariance); इस post और द्वारा जॉन स्कीट

1

चेक अपनी परियोजना के लिए ढांचे के लक्ष्य संस्करण जवाब की जाँच करें। यह कोड केवल .NET 4 में काम करेगा।

संबंधित मुद्दे