본문으로 바로가기
반응형

IComparable 인터페이스를 이용한 객체의 정렬

 C#의 컬렉션은 대부분 Sort메서드를 제공하는데 다음과 같이 IComparable 인터페이스를 구현해야 정상적으로 동작한다. IComparable 인터페이스는 자신과 비교할 매개변수를 비교하여 결과를 반환하는 CompreTo 메서드를 만들도록 약속하고있다. 매개 변수 형식이 object 형식으로 되어 있으므로 프로그램 목적에 맞게 캐스팅하여 처리해야 한다.

interface IComparable  //  IComparable의 I는 인터페이스를 뜻하며, 인터페이스는 반드시 구현해야하는 클래스이다.
{

   int CompareTo(object obj);

}

 C#의 System에 정의되어 있는 int, double, string 등의 기본 형식들은 ICompable 인터페이스를 기반으로 정의되어 있어서 이들 기본 형식을 보관한 컬렉션은 Sort 메서드를 이용하여 정렬할 수 있다. 사용자가 정의한 클래스나 구조체는 여러 필드나 속성을 포함할 수 있으므로 어떤 기준으로 정렬할 지를 사용자가 지정해야한다. 사용자가 클래스를 정의할 때 IComparable 인터페이스 기반으로 정의하고 CompareTo 메서드를 정의하면 객체의 컬렉션에서 Sort 메서드를 사용할 수 있다.

using System;
using System.Collections.Generic;
namespace _20200821_002
{
    class Program
    {
        class Fact : IComparable
        {
            public string Name;
            public int Age;
            public string Gender;

            public int CompareTo(object obj)
            {
                // throw new NotImplementedException();  // 메서드를 생성했는데 자동으로 생성된 코드이다.
                // 까먹고 코드를 안짜는 것을 방지해서 오류를 내는 코드이다.
                // 반드시 NotImplementedException  를 지우고 코드를 짜야한다.

                Fact aFact = (Fact)obj;  // obj 객체생성
                return this.Age.CompareTo(aFact.Age); // 나이순으로 정렬하는 구문을 리턴

                //return Age.CompareTo(((Fact)obj).Age);
            }

            public override string ToString()
            {
                return string.Format($"[{Name},{Age},{Gender}]");
            } 
        }
        static void Main(string[] args)
        {
            List<Fact> aList = new List<Fact>();
            Fact Temp = new Fact();
            Temp.Name = "그놈";
            Temp.Age = 50;
            Temp.Gender = "남자";
            aList.Add(Temp);

            Temp = new Fact();
            Temp.Name = "그녀";
            Temp.Age = 22;
            Temp.Gender = "여자";
            aList.Add(Temp);

            Temp = new Fact();
            Temp.Name = "그놈";
            Temp.Age = 28;
            Temp.Gender = "남자";
            aList.Add(Temp);

            Temp = new Fact();
            Temp.Name = "그녀";
            Temp.Age = 39;
            Temp.Gender = "여자";
            aList.Add(Temp);

            Temp = new Fact();
            Temp.Name = "그녀";
            Temp.Age = 31;
            Temp.Gender = "여자";
            aList.Add(Temp);

            foreach (var vTemp in aList)
           {
                Console.WriteLine(vTemp);
           }

            Console.WriteLine();
            aList.Sort();   // 배열 정렬 구문
            foreach (var vTemp in aList)
            {
                Console.WriteLine(vTemp);
            }
        }
    }
}

실행화면(나이순으로 정렬된 것을 볼 수 있다)

 

이번엔 예술가들을 태어난 순으로 정렬시켜보자.

using System;
using System.Collections.Generic;
namespace _20200821_002_IComparable2
{
    class Program
    {
        static void Main(string[] args)
        {
            Artists[] famousArtists =
            {
               new Artists("레오나르도 다빈치", "이탈리아", 1452, 1519),
               new Artists("빈센트 반 고흐", "네덜란드", 1853,  1890),
               new Artists("클로드 모네",  "프랑스", 1840,  1926),
               new Artists("파블로 피카소",  "스페인", 1881,  1973),
               new Artists("베르메르",  "네덜란드", 1632,  1675),
               new Artists("르노아르",  "프랑스", 1841,  1919)
            };

            List<Artists> artists19C = new List<Artists>();
            foreach (var artist in famousArtists)
            {
                if (artist.Birth > 1800 && artist.Birth <= 1900)
                    artists19C.Add(artist);
            }

            // IComparable을 사용하는 방법
            artists19C.Sort();
            Console.WriteLine("19세기 미술가를 탄생 순 정렬: IComparable");
            foreach (var a in artists19C)
                Console.WriteLine(a.ToString());
        }
    }

    class Artists : IComparable
    {
        public string Name { get; set; }
        public string Country { get; set; }
        public int Birth { get; set; }
        public int Die { get; set; }

        public Artists(string name, string country, int birth, int die)
        {
            Name = name;
            Country = country;
            Birth = birth;
            Die = die;
        }

        public int CompareTo(object obj)
        {
            //Artists a = (Artists)obj;
            //return this.Birth.CompareTo(a.Birth);
            return Birth.CompareTo(((Artists)obj).Birth);
        }

        public override string ToString()
        {
            return string.Format("{0}, {1}, {2}, {3}", Name, Country, Birth, Die);
        }
    }
}

태어난 순으로 정렬

 

반응형

'개발자과정준비 > C#' 카테고리의 다른 글

[C#] 시간(DateTime, TimeSpan, Diagnostics.Stopwatch)  (0) 2020.09.19
[C#] LiNQ  (0) 2020.08.29
[C#] List<T> 컬렉션, List<T>와 배열의 정렬  (0) 2020.08.28
[C#] 컬렉션, ArrayList  (0) 2020.08.24
[C#] Random 클래스  (0) 2020.08.23