2010-07-12 8 views
238

Dato il seguente codice e i suggerimenti forniti in this question, ho deciso di modificare questo metodo originale e chiedere se ci sono valori nell'IEnumarable restituirlo, se non restituire un oggetto IEnumerable senza valori.Come posso restituire un IEnumerable vuoto?

Ecco il metodo:

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 
      }); 
     } 

Dal momento che tutto è dentro l'istruzione return, non so come avrei potuto fare questo. Qualcosa come questo funziona?

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>(); 
      } 
     } 

Il metodo sopra non funziona e in effetti non è previsto; Ho appena sentito che illustra le mie intenzioni. Ritengo di dover specificare che il codice non funziona perché non è possibile creare un'istanza di una classe astratta.

Ecco il codice chiamante, io non voglio che per ricevere un nulla IEnumerable in qualsiasi momento:

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; 
      } 

     } 

Grazie per il vostro tempo.

+2

Guardando il codice qui si dovrebbe usare dei rendimenti e pausa resa. –

risposta

407

È possibile utilizzare list ?? Enumerable.Empty<Friend>(), o hanno FindFriends ritorno Enumerable.Empty<Friend>()

+5

Cambierà le cose se viene restituito, ad esempio, 'nuova lista ()' dal momento che verrà trasmesso a 'IEnumerable ' quando viene restituito da tale metodo? –

+60

'nuova lista ()' è un'operazione più costosa perché creerebbe un'istanza di un elenco (e allocerà memoria per esso nel processo) –

76

Quanto a me, più elegante modo è yield break

+5

Ma questo è se si utilizza rendimento restituito e tale, non è vero? – Svish

+10

+1 perché il suo codice dovrebbe usare correttamente il rendimento per il modo in cui sta lavorando con IEnumerable –

+5

Perdonami la mia ignoranza sull'argomento, ma potresti per favore illustrare come utilizzare l'interruzione di rendimento in questo contesto? Ho visto esempi solo per cicli, ma questo non dipinge un'immagine chiara per me. –

1

penso che il modo più semplice sarebbe

return new Friend[0]; 

I requisiti del ritorno sono semplicemente che il metodo restituisce un oggetto che implementa IEnumerable<Friend>. Il fatto che in diverse circostanze si restituiscano due diversi tipi di oggetti è irrilevante, purché entrambi implementino IEnumerable.

+4

Enumerable.Empty restituisce effettivamente una matrice vuota di T (T [0]), con il vantaggio che lo stesso array vuoto viene riutilizzato. Si noti che questo approccio non è ideale per gli array non vuoti, poiché gli elementi possono essere modificati (tuttavia non è possibile ridimensionare un array, il ridimensionamento implica la creazione di una nuova istanza). –

7

Questo è ovviamente solo una questione di preferenza personale, ma mi piacerebbe scrivere questa funzione utilizzando dei rendimenti:

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 
       } 
     } 
    } 
} 
Problemi correlati