Biorąc pod uwagę następujący kod i sugestie podane w tym pytaniu , postanowiłem zmodyfikować tę oryginalną metodę i zapytać, czy w IEnumarable są jakieś wartości, zwróć ją, jeśli nie, zwróć IEnumerable bez wartości.
Oto metoda:
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
});
}
Ponieważ wszystko znajduje się w instrukcji return, nie wiem, jak to zrobić. Czy coś takiego mogłoby działać?
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>();
}
}
Powyższa metoda nie działa, a właściwie nie powinna; Po prostu czuję, że to ilustruje moje intencje. Wydaje mi się, że powinienem określić, że kod nie działa, ponieważ nie można utworzyć instancji klasy abstrakcyjnej.
Oto kod wywołujący, nie chcę, aby w dowolnym momencie odbierał pusty 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;
}
}
Dziękuję za Twój czas.
c#
ienumerable
Sergio Tapia
źródło
źródło
Odpowiedzi:
Możesz użyć
list ?? Enumerable.Empty<Friend>()
lub otrzymaćFindFriends
zwrotEnumerable.Empty<Friend>()
źródło
new List<Friend>()
skoro zostanie onoIEnumerable<Friend>
przywrócone po powrocie z tej metody?new List<Friend>()
jest droższą operacją, ponieważ stworzyłby instancję listy (i przydzieliłby dla niej pamięć)Mógłbyś wrócić
Enumerable.Empty<T>()
.źródło
Jak dla mnie, najbardziej elegancki jest sposób
yield break
źródło
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; } }
To oczywiście tylko kwestia osobistych preferencji, ale napisałbym tę funkcję, używając zwrotu z zysku:
źródło
Myślę, że najprostszy sposób byłby
Wymagania dotyczące zwrotu polegają jedynie na tym, że metoda zwraca obiekt, który implementuje
IEnumerable<Friend>
. Fakt, że w różnych okolicznościach zwracane są dwa różne rodzaje obiektów, jest nieistotny, o ile oba implementują IEnumerable.źródło
źródło