2011-06-24 9 views
7

मेरे पास एक दिलचस्प मुद्दा है जहां कक्षा को कक्षा से विरासत में प्राप्त किया जाता है जो आईनेमरेबल लागू करता है, लेकिन मैं यह भी चाहता हूं कि कक्षा एक अलग प्रकार के लिए आईनेमरेबल को कार्यान्वित करे। सबकुछ IENumerable एक्सटेंशन विधियों को छोड़कर काम करता है, जिसका अर्थ है कि मैं बिना किसी पंक्ति के डिफ़ॉल्ट रूप से ऑब्जेक्ट्स के लिए कोई LINQ नहीं कर सकता। क्या किसी के पास लगातार कास्टिंग के अलावा कोई विचार है?मेरी कक्षा LINQ का ऑब्जेक्ट्स का उपयोग क्यों नहीं कर सकती जब मेरी कक्षा IENumerable <T> कई बार लागू करती है?

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace LinqTesting 
{ 
    public class Trucks<T> : Vehicles, IEnumerable<Truck> 
    {  
     public Trucks() 
     {  
      // Does Compile 
      var a = ((IEnumerable<Truck>)this).FirstOrDefault(); 
      // Doesn't Compile, Linq.FirstOrDefault not found 
      var b = this.FirstOrDefault(); 
     }  

     public new IEnumerator<Truck> GetEnumerator() { throw new NotImplementedException(); } 
    }  

    public class Vehicles : IEnumerable<Vehicle> 
    {  
     public IEnumerator<Vehicle> GetEnumerator() { throw new NotImplementedException(); } 
     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new NotImplementedException(); } 
    }  

    public class Vehicle { } 

    public class Truck : Vehicle { } 
}  
+2

क्या आपका ट्रक ऑब्जेक्ट दो आईनेमरेबल प्रकारों को विरासत में नहीं मिला है? आप संकलक को यह अनुमान लगाने के लिए कैसे उम्मीद करते हैं कि आप किस अनन्य प्रकार का उपयोग करना चाहते हैं, अपने इच्छित व्यक्ति को अपस्टास्टिंग करने का प्रयास करें और फिर फर्स्टऑरडिफॉल्ट –

उत्तर

6

वास्तव में आप कर सकते हैं, लेकिन आप सामान्य प्रकार के अनुमान का लाभ नहीं ले जा सकते हैं, क्योंकि अपनी कक्षा दो अलग अलग प्रकार के दो IEnumerable<T> लागू करता है और संकलक पता नहीं कर सकते हैं आप किस प्रकार का उपयोग करना चाहते हैं।

आप इसे सीधे कोई निर्दिष्ट कर सकते हैं, जैसे:

var b = this.FirstOrDefault<Truck>(); 
+0

यह वास्तव में मैं क्या खो रहा था। यह उलझन में था क्योंकि इंटेलिजेंस विधि दिखाते हुए पॉपअप करेगा, लेकिन यह उसी पंक्ति में त्रुटि भी दिखाएगा क्योंकि संकलक अब सामान्य प्रकार के अनुमान का लाभ नहीं ले सकता था। – Daryl

4

IEnumerable एकाधिक समय को लागू करने संकलक, जो IEnumerable <> यह इस बात के लिए विचार करना चाहिए confuses।

IEnumerable<Vehicle> or IEnumerable<Truck>? 

this.FirstOrDefault<Truck>() might compile. 
0

सार्वजनिक नई IEnumerator GetEnumerator()

कि लाइन खाल में new कीवर्ड GetEnumerator() विधि वाहन वर्ग से विरासत में मिली है। मुझे यकीन नहीं है कि यह काम करेगा, लेकिन शायद इसके बजाय explicit interface implementation आज़माएं।

+0

कुछ इंटरफेस के लिए स्पष्ट इंटरफ़ेस कार्यान्वयन का उपयोग करना और दूसरों के लिए निहित विस्तार विधि समाधान को नहीं बदला जाता है। यह केवल तभी मदद करता है जब आप 'GetEnumerator() 'को सीधे कॉल कर रहे हों, इसलिए इससे मदद नहीं मिलती है। – binki

7

करने के लिए अपने कोड में परिवर्तित करें:

public class Trucks : Vehicles<Truck> 
{  
}  

public class Vehicles<T> : IEnumerable<T> 
    where T : Vehicle 
{  
}  

public class Vehicle { } 

public class Truck : Vehicle { } 
+0

धीमा करने के लिए बस कुछ मिनट;) – Clayton

+0

@ क्लेटन - यह जीवन है ;-) –

+0

दुर्भाग्य से मुझे बेस क्लास कोड तक पहुंच नहीं है, लेकिन यह सही समाधान होगा। मुझे यह देखना होगा कि क्या मैं उस बदलाव को प्राप्त कर सकता हूं। धन्यवाद! – Daryl

2

ऐसा लगता है कि थोड़े अटक कर रहे हैं। अपने टाइपिंग को कम करने के लिए यहां एक सुझाव दिया गया है। आप अपने कुछ सामान्यतः उपयोग किए गए IENumerable <> प्रकारों के लिए एक एक्सटेंशन विधि बना सकते हैं।

var a = myList.AsTruckEnumerable().FirstOrDefault(); 

public static partial class Extensions 
{ 
    public static IEnumerable<Truck> AsTruckEnumerable (this IEnumerable<Truck> trucks) 
    { 
    return trucks; 
    } 
} 

public class Trucks<T> : Vehicles, IEnumerable<Truck> 
{  
    public Trucks() 
    {  
     // Does Compile 
     var a = ((IEnumerable<Truck>)this).FirstOrDefault(); 

     // Does compile 
     var b = this.AsTruckEnumerable().FirstOrDefault(); 
     // Doesn't Compile, Linq.FirstOrDefault not found 
     //var b = this.FirstOrDefault(); 
    }  

    public new IEnumerator<Truck> GetEnumerator() { throw new NotImplementedException(); } 
}  
संबंधित मुद्दे