빈 IEnumerable을 어떻게 반환합니까?


329

다음 코드 와이 질문에 제공된 제안을 감안할 때이 원래 방법을 수정하고 값이없는 IEnumerable을 반환하지 않으면 IEnumarable에 값이 있는지 확인하기로 결정했습니다.

방법은 다음과 같습니다.

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

모든 것이 return 문 안에 있기 때문에 어떻게 할 수 있는지 모르겠습니다. 이런 식으로 작동합니까?

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

위의 방법은 작동하지 않으며 실제로는 그렇지 않습니다. 나는 그것이 내 의도를 설명한다고 생각합니다. 추상 클래스의 인스턴스를 만들 수 없으므로 코드가 작동하지 않도록 지정해야한다고 생각합니다.

다음은 호출 코드입니다. 언제든지 null 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
여기서 코드를 보면 yield return 및 yield break를 사용해야합니다.
Chris Marisic

답변:


575

을 사용 list ?? Enumerable.Empty<Friend>()하거나 FindFriends돌아올 수 있습니다Enumerable.Empty<Friend>()


7
예를 들어, 그 방법에서 돌아 왔을 때 new List<Friend>()캐스트되기 때문에 그것이 바뀌면 상황이 바뀌겠습니까 IEnumerable<Friend>?
Sarah Vessels

73
new List<Friend>()목록의 인스턴스를 만들고 프로세스에 메모리를 할당하기 때문에 비용이 많이 드는 작업입니다.
Igor Pashchuk


105

가장 우아한 방법은 yield break


8
그러나 그것이 수익률 등을 사용한다면 그렇지 않습니까?
Svish

15
코드가 올바르게 +1
이면

6
주제에 대한 나의 무지를 용서하지만,이 맥락에서 항복 중단을 사용하는 방법을 설명해 주시겠습니까? for 루프에서만 예제를 보았지만 명확한 그림을 그리지는 않습니다.
세르지오 타 피아

예를 들어 답변을 업데이트했습니다. 내가 동의하는 가장 우아한 방법입니다. :)
Johny Skovdal

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

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])를 반환합니다. 이 방법은 요소를 수정할 수 있기 때문에 비어 있지 않은 배열에는 적합하지 않습니다 (하지만 배열의 크기를 조정할 수는 없지만 크기를 조정하려면 새 인스턴스를 생성해야 함).
Francis Gagné

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>();
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.