मैं एक खाली IEnumerable कैसे लौटा सकता हूं?


329

निम्नलिखित कोड और इस प्रश्न में दिए गए सुझावों को देखते हुए , मैंने इस मूल पद्धति को संशोधित करने का फैसला किया है और पूछा है कि क्या IEnumarable में कोई मान हैं, यदि कोई मान के साथ IEnumerable नहीं लौटाता है।

यहाँ विधि है:

public IEnumerable<Friend> FindFriends()
        {
            //Many thanks to Rex-M for his help with this one.
            //https://stackoverflow.com/users/67/rex-m

            return doc.Descendants("user").Select(user => new Friend
            {
                ID = user.Element("id").Value,
                Name = user.Element("name").Value,
                URL = user.Element("url").Value,
                Photo = user.Element("photo").Value
            });
        }

चूंकि सब कुछ रिटर्न स्टेटमेंट के अंदर है, मुझे नहीं पता कि मैं यह कैसे कर सकता हूं। क्या यह काम पसंद आएगा?

public IEnumerable<Friend> FindFriends()
        {
            //Many thanks to Rex-M for his help with this one.
            //https://stackoverflow.com/users/67/rex-m
            if (userExists)
            {
                return doc.Descendants("user").Select(user => new Friend
                {
                    ID = user.Element("id").Value,
                    Name = user.Element("name").Value,
                    URL = user.Element("url").Value,
                    Photo = user.Element("photo").Value
                });
            }
            else
            { 
                return new IEnumerable<Friend>();
            }
        }

उपरोक्त विधि काम नहीं करती है, और वास्तव में यह माना नहीं जाता है; मुझे लगता है कि यह मेरे इरादों को दिखाता है। मुझे लगता है कि मुझे यह निर्दिष्ट करना चाहिए कि कोड काम नहीं करता है क्योंकि आप एक अमूर्त वर्ग का उदाहरण नहीं बना सकते हैं।

यहाँ कॉलिंग कोड है, मैं नहीं चाहता कि यह किसी भी समय अशक्त IEnumerable प्राप्त करें:

private void SetUserFriends(IEnumerable<Friend> list)
        {
            int x = 40;
            int y = 3;


            foreach (Friend friend in list)
            {
                FriendControl control = new FriendControl();
                control.ID = friend.ID;
                control.URL = friend.URL;
                control.SetID(friend.ID);
                control.SetName(friend.Name);
                control.SetImage(friend.Photo);

                control.Location = new Point(x, y);
                panel2.Controls.Add(control);

                y = y + control.Height + 4;
            } 

        }

आपके समय के लिए शुक्रिया।


2
यहां कोड को देखते हुए आपको यील्ड रिटर्न और यील्ड ब्रेक का उपयोग करना चाहिए।
बजे क्रिस मैरिसिक

जवाबों:


575

आप उपयोग कर सकते हैं list ?? Enumerable.Empty<Friend>(), या FindFriendsवापस आ सकते हैंEnumerable.Empty<Friend>()


7
क्या वह चीजों को बदल देगा यदि वह लौटा, कहो, new List<Friend>()क्योंकि यह IEnumerable<Friend>उस पद्धति से वापस आने पर डाली जाएगी ?
सारा वेसल्स

73
new List<Friend>()एक अधिक महंगा ऑपरेशन है क्योंकि यह एक सूची का एक उदाहरण पैदा करेगा (और इस प्रक्रिया में इसके लिए मेमोरी आवंटित करेगा)
इगोर पश्चुक


105

मेरे लिए, सबसे सुरुचिपूर्ण तरीका है yield break


8
लेकिन अगर आप पैदावार वापसी का उपयोग करते हैं और ऐसा नहीं है, तो क्या यह है?
सविश

15
अपने कोड के रूप में +1 सही तरीके से उपज का उपयोग करना चाहिए जिस तरह से वह IEnumerable के साथ काम कर रहा है
क्रिस मैरिसिक

6
इस विषय पर मेरी अज्ञानता को क्षमा करें, लेकिन क्या आप इस संदर्भ में उपज तोड़ने का उपयोग करने का तरीका बता सकते हैं? मैंने केवल लूप के लिए उदाहरण देखे हैं, लेकिन यह मेरे लिए एक स्पष्ट तस्वीर नहीं चित्रित करता है।
सर्जियो तापिया

एक उदाहरण के साथ उत्तर को अपडेट करें। वास्तव में यह करने का सबसे सुरुचिपूर्ण तरीका है जिससे मैं सहमत हो जाऊंगा। :)
जॉनी स्कोवडाल

4
संपादन को सहकर्मी समीक्षा में खारिज कर दिया गया, इसलिए यहां उदाहरण मैं @Pyritie के बारे में बात कर रहा था - स्वरूपण हालांकि गड़बड़ हो जाता है, इसलिए मैंने इसे pastebin.com/X9Z49Vq1 के साथ जोड़ा :public IEnumerable<Friend> FindFriends() { if(!userExists) yield break; foreach(var descendant in doc.Descendants("user").Select(user => new Friend { ID = user.Element("id").Value, Name = user.Element("name").Value, URL = user.Element("url").Value, Photo = user.Element("photo").Value })) { yield return descendant; } }
जॉनी स्केडल

8

यह निश्चित रूप से केवल व्यक्तिगत पसंद की बात है, लेकिन मैं इस फ़ंक्शन को उपज रिटर्न का उपयोग करके लिखूंगा:

public IEnumerable<Friend> FindFriends()
{
    //Many thanks to Rex-M for his help with this one.
    //http://stackoverflow.com/users/67/rex-m
    if (userExists)
    {
        foreach(var user in doc.Descendants("user"))
        {
            yield return new Friend
                {
                    ID = user.Element("id").Value,
                    Name = user.Element("name").Value,
                    URL = user.Element("url").Value,
                    Photo = user.Element("photo").Value
                }
        }
    }
}

1

मुझे लगता है कि सबसे सरल तरीका होगा

 return new Friend[0];

वापसी की आवश्यकताएं केवल यह हैं कि विधि एक वस्तु लौटाती है जो लागू होती है IEnumerable<Friend>। तथ्य यह है कि विभिन्न परिस्थितियों में आप दो अलग-अलग प्रकार की वस्तुओं को वापस करते हैं, अप्रासंगिक है, जब तक दोनों IEnumerable को लागू करते हैं।


5
Enumerable.Empty <T> वास्तव में T (T [0]) की एक खाली सरणी देता है, इस लाभ के साथ कि उसी खाली सरणी का पुन: उपयोग किया जाता है। ध्यान दें कि यह दृष्टिकोण गैर-खाली सरणियों के लिए आदर्श नहीं है, क्योंकि तत्वों को संशोधित किया जा सकता है (हालांकि एक सरणी को आकार नहीं दिया जा सकता है, आकार बदलना एक नया उदाहरण बनाना शामिल है)।
फ्रांसिस गग्ने

0
public IEnumerable<Friend> FindFriends()
{
    return userExists ? doc.Descendants("user").Select(user => new Friend
        {
            ID = user.Element("id").Value,
            Name = user.Element("name").Value,
            URL = user.Element("url").Value,
            Photo = user.Element("photo").Value
        }): new List<Friend>();
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.