2012-07-11 9 views
18

लौटने पर मैं जेनेरिक और आईनेमरेबल अबाइट के साथ गड़बड़ कर रहा हूं, लेकिन मैं थोड़ी देर से अटक गया हूं। यहाँ मुझे क्या करना कोशिश कर रहा हूँ है: - (?) मैं एक विधि है कि किसी भी संग्रह प्रकार रिटर्न चाहते हैं कि IEnumerable लागू करता है - (ताकि जैसे: सूची, ढेर, कतार, ...)एक सामान्य आईनेमेरेबल <T>

इसके अलावा, मैं किसी भी डेटाटाइप के किसी संग्रह प्रकार को वापस करने में सक्षम होना चाहता हूं। तो मैं इस विधि एक List<double> के रूप में एक Stack<int> के साथ ही एक List<string>, वापस जाने के लिए ... के साथ-साथ, वगैरह वगैरह

public IEnumerable<T> returnSomething() 
    { 
     Stack<int> stackOfInts = new Stack<int>(); 
     List<string> listOfStrings = new List<string>(); 
     return stackOfInts; 
    } 

इस मैं अब तक की कोशिश की है है सक्षम होना चाहते हैं। इस हालांकि काम नहीं करता है, मैं इस त्रुटि मिलती है:

Cannot implicitly convert type 'System.Collections.Generic.Stack<int>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?) 

हालांकि, अगर मैं IEnumerable<int> लिए विधि हस्ताक्षर में IEnumerable<T> की जगह, मैं प्रकार int के किसी भी संग्रह लौट सकते हैं। हालांकि इसका मतलब है कि अब मैं ListOfStrings वापस नहीं कर सकता।

आप अपने पद्धति के लिए एक generic type parameter जोड़ने की जरूरत है किसी भी सुझाव या विचार :)

उत्तर

26

का स्वागत करेंगे:

public IEnumerable<T> ReturnSomething<T>() 
{ 
    Stack<T> stackOfT = new Stack<T>(); 
    return stackOfT; 
} 

प्रकार पैरामीटर विधि नाम के बाद दिखाई देता है, लेकिन मानकों से पहले। एक से अधिक प्रकार के पैरामीटर के साथ एक विधि भी संभव है।

जब आप विधि कॉल आप प्रकार निर्दिष्ट कर सकते हैं:

IEnumerable<int> myInts = ReturnSomething<int>(); 
+0

धन्यवाद, यह वास्तव में काम करता है, लेकिन अब मैं नहीं कर सकते जोड़ने के लिए लग रहे हैं ढेर के लिए कुछ भी ..stackOfInts.Push (3); अगर मैं इसे आज़माता हूं, तो यह कहता है: "सबसे अच्छा ओवरलोडेड मैच .. कुछ अमान्य तर्क हैं"। कोई विचार? – Thousand

+0

@ जेनडो: आप केवल 'टी' को 'स्टैक ' में जोड़ सकते हैं। 3 जरूरी नहीं है 'टी'। जब तक आप एक [जेनेरिक टाइप बाधा] (http://msdn.microsoft.com/en-us/library/d5x73970.aspx) जोड़ते हैं, आपको पता नहीं है कि 'टी' क्या है, इसलिए आप एक भी निर्माण नहीं कर सकते हैं - ऐसा करने के लिए आपको 'नई()' बाधा की आवश्यकता होगी। आप क्या करने की कोशिश कर रहे हैं, और आपको इसकी आवश्यकता क्यों है? –

+1

मुझे विशेष रूप से किसी भी चीज के लिए इसकी आवश्यकता नहीं है, मैं सिर्फ चीजों का एक गुच्छा कोशिश कर रहा हूं। लेकिन मुझे अब मिल गया, धन्यवाद। – Thousand

10

चाल घोषित करने के लिए<T> सही, अगर आप सामान्य <T> परिभाषित करते हैं, तो आप अपने तरीकों में इसे करने के लिए छड़ी करने के लिए है, इसलिए है अगर आपके पास IEnumerable<T> है तो अपनी विधि में कहीं और आपको <T> और <int> या किसी अन्य प्रकार का उपयोग करना चाहिए।

यह जब आप वास्तव में उपयोग आप सामान्य प्रकार आप सामान्य <T> कोई वास्तविक प्रकार के लिए स्थानापन्न केवल उत्तरार्द्ध है।

एक नमूना देखें

class Foo<T> 
{ 
    public IEnumerable<T> GetList() 
    { 
     return new List<T>(); 
    } 

    public IEnumerable<T> GetStack() 
    { 
     return new Stack<T>(); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Foo<int> foo = new Foo<int>(); 
     IEnumerable<int> list = foo.GetList(); 
     IEnumerable<int> stack = foo.GetStack(); 

     Foo<string> foo1 = new Foo<string>(); 
     IEnumerable<string> list1 = foo1.GetList(); 
     IEnumerable<string> stack1 = foo1.GetStack(); 
    } 
} 
1

हाँ आप किसी भी प्रकार लौट सकते हैं यदि आप मैं इस तरह Enumerable<T> to IEnumerable<dynamic>

बदलने के लिए:

public IEnumerable<dynamic> returnSomething() 
{ 
..... 
+2

जेनिक्स का उपयोग क्यों करें यदि आप खिड़की से सुरक्षा को फेंकने जा रहे हैं ... – Adam

+0

यह वास्तव में एक हैक की तरह लगता है .. मैंने कोशिश की और यह संकलन भी नहीं किया। – Thousand

+0

@codesparkle मैं आपके बिंदु से सहमत हूं और दृढ़ता से इसका भी पालन करता हूं, लेकिन ऐसे समय होते हैं जब आपके पास दिए गए तीसरे पक्ष के एपीआई विधि रिटर्न प्रकार पर नियंत्रण नहीं होता है, इसलिए गतिशील इस तरह के मामले में उद्धारकर्ता है – HatSoft

2
public IEnumerable<T> returnSomething() 
{ 
    Stack<int> stackOfInts = new Stack<int>(); 
    return (IEnumerable<T>) stackOfInts; 
} 
1

प्रकार पैरामीटर द्वारा निर्दिष्ट किए जाने की आवश्यकता कहीं कॉलर।

या तो जब एक सामान्य वर्ग instantiating:

public class MyClass<T> 
{ 
    public IEnumerable<T> returnSomething() 
    { 
     Stack<T> stackOfTs = new Stack<T>(); 
     List<T> listOfTs = new List<T>(); 
     return stackOfTs; 
    } 
} 

var v = new MyClass<int>(); 
foreach(var item in v.returnSomething()) 
{ 
} 

या जब एक गैर सामान्य वर्ग के एक सामान्य विधि बुला:

public class MyClass 
{ 
    public IEnumerable<T> returnSomething<T>() 
    { 
     Stack<T> stackOfTs = new Stack<T>(); 
     List<T> listOfTs = new List<T>(); 
     return stackOfTs; 
    } 
} 


var v = new MyClass(); 
foreach(var item in v.returnSomething<int>()) 
{ 
}