순서 비교
- 상대적 순서를 결정하는데 쓰이는 표준 프로토콜
* IComparable 인터페이스들 (System.IComparable, System.IComparable<T>) * >, < 연산자
IComparable
namespace System
{
public interface IComparable<in T>
{
int CompareTo(T other);
}
}
namespace System
{
public interface IComparable
{
int CompareTo(object obj);
}
}
- 두개의 인터페이스는 간은 기능성을 제공
- 값 형식의 경우 형식에 안전한 제네릭 인터페이스가 비제네릭 인터페이스보다 빠름
- 대부분의 기반 형식은 두 인터페이스를 모두 구현함
- 커스텀 형식을 작성 할 때, 이 인터페이스들을 구현하는 경우도 있음
- CompareTo
* a가 b보다 뒤에 와야 하면 a.CompareTo(b)는 양수
* a가 b와 같은 위치에 와야 하면 a.CompareTo(b)는 0
* a가 b보다 앞에 와야 하면 a.CompareTo(b)는 음수
IComparable 대 Equals
- Equals가 true라면 CompareTo는 0을 돌려줘야 함
* CompareTo의 첫줄에 if(Equals(other)) return 0; 을 넣어주면 규칙을 위반할 가능성이 사라짐
- Equals가 false라면 CompareTo는 어떤 값이라도 돌려줄 수 있음
- 상등은 비교보다 더 까다롭게 적용할 수 있지만, 비교는 상등보다 더 까다로울 수 없음
ex) 대소문자 비교, 문화권에 따른 특수 문자 등
>, < 연산자
- 일반적으로 IComparable과 모순되지 않는 결과를 내도록 구현
- 일반적으로 >, < 연산자 구현시 IComparable도 구현
- IComparable 구현시 >, < 연산자를 구현하진 않는다.
- >, < 연산자를 구현하는 경우
* 형식에 고유한 '초과'와 '미만' 개념이 아주 강함
* 순서 비교를 수행하는 방법 또는 문맥이 단 하나
* 결과가 문화권에 관계없이 동일
// 예제: 음표를 나타내는 구조체
public struct Note : IComparable, IComparable<Note>, IEquatable<Note>
{
int semitonesFromA;
public int SemitonesFromA
{
get { return semitonesFromA; }
}
public Note(int semitonesFromA)
{
this.semitonesFromA = semitonesFromA;
}
// IComparable
public int CompareTo(object obj)
{
// 인자가 Note 타입이 아니라면
if(!(obj is Note))
{
throw new InvalidOperationException("CompareTo: 음표가 아님!");
}
else
{
// 제네릭 IComparable 쪽에서 연산
return CompareTo((Note)obj);
}
}
// IComparable<Note>
public int CompareTo(Note other)
{
// 실패의 여지가 없는 점검
if(Equals(other))
{
return 0;
}
else
{
return semitonesFromA.CompareTo(other.semitonesFromA);
}
}
// >, < 연산자
public static bool operator >(Note n1, Note n2) => n1.CompareTo(n2) > 0;
public static bool operator <(Note n1, Note n2) => n1.CompareTo(n2) < 0;
/**************************************************************************/
// Equals Custom
public override bool Equals(object obj)
{
if(!(obj is Note))
{
return false;
}
else
{
return Equals((Note)obj);
}
}
// IEquatable<Note>
public bool Equals(Note other) => semitonesFromA == other.semitonesFromA;
// GetHashCode Custom
public override int GetHashCode() => semitonesFromA.GetHashCode();
// ==, != 연산자
public static bool operator ==(Note n1, Note n2) => n1.Equals(n2);
public static bool operator !=(Note n1, Note n2) => !(n1 == n2);
'C#' 카테고리의 다른 글
[C#] AppContext (1) | 2023.08.30 |
---|---|
[C#] Process (1) | 2023.08.29 |
[C#] Environment (0) | 2023.08.28 |
[C#] Console (1) | 2023.08.27 |
[C#] 상등 비교 (IEquatable<T>) (0) | 2023.08.25 |
[C#] Guid (0) | 2023.08.24 |
[C#] Math (1) | 2023.08.23 |
[C#] Tuple (1) | 2023.08.22 |