상세 컨텐츠

본문 제목

foreach를 사용할 수 있는 일반화 클래스 -2

C#

by 메타 스토리 2023. 9. 5. 13:23

본문

List<Person>을 상속받는 방식과 IEnumerable<Person> 인터페이스를 구현하는 방식은 각각의 장단점이 있습니다. 어떤 방식을 선택할지는 상황과 요구사항에 따라 다를 수 있습니다.

List<Person> 상속 방식:

장점:
기본적인 리스트 동작을 모두 상속받으므로 리스트를 사용하는 다양한 메서드와 기능을 활용할 수 있습니다. 예를 들어 Add, Remove, Clear, Sort 등의 메서드를 쉽게 사용할 수 있습니다.
코드가 간결하며 직관적입니다.
단점:
List<Person> 클래스를 직접 상속받기 때문에 다중 상속이 필요한 경우에는 제한이 있을 수 있습니다.
클래스의 구조를 변경하기 위해 해당 클래스의 소스 코드에 직접 접근해야 할 수 있으므로 라이브러리 클래스일 경우 수정이 어려울 수 있습니다.
IEnumerable<Person> 인터페이스 구현 방식:

장점:
인터페이스를 구현함으로써 클래스가 다른 클래스와 호환성을 가질 수 있습니다. 이 클래스를 다른 컬렉션과 함께 사용할 때 더 유연성을 제공합니다.
클래스의 동작을 더 정확하게 제어할 수 있으며, 필요한 메서드와 속성만 노출시킬 수 있습니다.
단점:
컬렉션의 기본 동작을 사용하기 위해 별도의 구현이 필요하며, 코드가 상대적으로 더 복잡해질 수 있습니다.
필요한 경우 컬렉션 관련 메서드와 동작을 직접 구현해야 하므로 시간과 노력이 더 필요합니다.
따라서 어떤 방식을 선택할지는 프로젝트의 특정 요구사항과 목표에 따라 다릅니다. 간단한 리스트를 다루는 경우에는 List<Person>을 상속받는 방식이 편리할 수 있지만, 라이브러리나 클래스의 재사용성을 고려하거나 더 정교한 컨트롤이 필요한 경우에는 IEnumerable<Person> 인터페이스 구현 방식이 유용할 수 있습니다.

 

다음은 IEnumerable<Person> 인터페이스를 구현한 PeopleCollection 클래스를 사용하여 다른 컬렉션과 함께 사용하는 예제입니다.

using System;
using System.Collections.Generic;
using System.Linq;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override string ToString()
    {
        return $"{Name}, {Age} years old";
    }
}

public class PeopleCollection : IEnumerable<Person>
{
    private List<Person> people = new List<Person>();

    public void AddPerson(Person person)
    {
        people.Add(person);
    }

    public IEnumerator<Person> GetEnumerator()
    {
        return people.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

class Program
{
    static void Main()
    {
        // PeopleCollection 클래스를 생성
        PeopleCollection peopleCollection = new PeopleCollection();

        // Person 객체를 PeopleCollection에 추가
        peopleCollection.AddPerson(new Person { Name = "Alice", Age = 30 });
        peopleCollection.AddPerson(new Person { Name = "Bob", Age = 25 });

        // PeopleCollection 클래스를 다른 컬렉션과 함께 사용
        List<Person> peopleList = peopleCollection.ToList();
        Console.WriteLine("People in the list:");
        foreach (var person in peopleList)
        {
            Console.WriteLine(person);
        }
    }
}

People in the list:
Alice, 30 years old
Bob, 25 years old

 

이 예제에서는 PeopleCollection 클래스를 사용하여 Person 객체를 저장하고, 이 클래스를 List<Person>으로 변환하여 다른 컬렉션과 함께 사용합니다. 이렇게 함으로써 PeopleCollection 클래스가 IEnumerable<Person>을 구현함으로써 다른 컬렉션과 호환성을 가지며 더 유연하게 사용될 수 있습니다.

 

Person 클래스가 IEnumerable<Person>을 상속받으면 ToList() 메서드를 사용하여 List<Person>으로 변환할 수 있습니다. 이와 유사하게 다양한 컬렉션 타입으로 변환할 수 있습니다. 몇 가지 가능한 변환 방법은 다음과 같습니다:

ToArray(): Person[] 배열로 변환할 수 있습니다.
ToDictionary(): Dictionary<TKey, TValue>로 변환할 수 있습니다. 이 경우, Person 객체의 속성을 기반으로 키-값 쌍을 생성할 수 있습니다.
ToHashSet(): HashSet<Person>으로 변환할 수 있습니다. 중복 요소를 제거하고 고유한 요소만 포함합니다.
ToLookup(): ILookup<TKey, TElement>로 변환할 수 있습니다. 그룹화된 결과를 표현할 때 사용됩니다.
ToQueue(), ToStack(): Queue<Person> 또는 Stack<Person>으로 변환할 수 있습니다.
이렇게 다양한 컬렉션 타입으로 변환할 수 있는 이점은 다른 컨텍스트에서 필요한 데이터 구조로 데이터를 쉽게 전환할 수 있다는 것입니다. 예를 들어, LINQ 쿼리를 사용하여 데이터를 필터링하거나 변환한 후 원하는 형식의 컬렉션으로 변환할 때 유용합니다.

 

아래는 Person 클래스 목록에서 LINQ 쿼리를 사용하여 나이(Age)를 기준으로 그룹화한 다음 이를 ILookup<TKey, TElement> 컬렉션으로 변환하는 예제입니다. 이 예제에서는 각 그룹의 키(Age)와 해당 키에 속하는 Person 객체 목록을 포함하는 ILookup<int, Person>을 생성합니다.

 

using System;
using System.Collections.Generic;
using System.Linq;

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        List<Person> people = new List<Person>
        {
            new Person { Name = "Alice", Age = 25 },
            new Person { Name = "Bob", Age = 30 },
            new Person { Name = "Charlie", Age = 25 },
            new Person { Name = "David", Age = 30 },
        };

        // LINQ 쿼리를 사용하여 나이를 기준으로 그룹화
        var ageGroups = from person in people
                        group person by person.Age;

        // ILookup<int, Person>으로 변환
        ILookup<int, Person> ageLookup = ageGroups.ToLookup(group => group.Key, group => group.First());

        // 결과 출력
        foreach (var ageGroup in ageLookup)
        {
            Console.WriteLine($"Age: {ageGroup.Key}");
            foreach (var person in ageGroup)
            {
                Console.WriteLine($"Name: {person.Name}");
            }
            Console.WriteLine();
        }
    }
}

이 예제에서는 ageGroupsILookup<int, Person>으로 변환하기 위해 ToLookup 메서드를 사용합니다. 그런 다음 ILookup 컬렉션을 반복하여 그룹화된 결과를 출력합니다.

 

Age: 25
Name: Alice
Name: Charlie

Age: 30
Name: Bob
Name: David

 

나이(Age)를 키로 하고 해당 나이에 속하는 사람들의 이름을 나열한 것을 볼 수 있습니다.

 

 

'C#' 카테고리의 다른 글

Entity Framework  (0) 2023.09.05
LINQ 쿼리  (0) 2023.09.05
LinkedList<T>  (0) 2023.09.05
HashSet<T>  (0) 2023.09.05
foreach를 사용할 수 있는 일반화 클래스  (0) 2023.09.05

관련글 더보기