[C#] IReadOnlyCollection

LeeTaeHwa·2023년 3월 18일
0

C#

목록 보기
3/4

Introduction


ICollection 인터페이스를 통해서 컨테이너 클래스에 대한 기본 틀을 제공받는다. 그렇다면 읽기전용 컨테이너를 만들고 싶을 땐 어떻게 해야 할까? 그에 대한 대답이 바로 IReadOnlyCollection 이다. ICollection 인터페이스와 비교 해보았을 때에 추가, 삭제 기능 등이 빠져서 순수하게 컨테이너의 데이터를 참조하는 행위만 가능하다.

본 인터페이스에 대한 코드는 다음과 같다.

public interface IReadOnlyCollection<out T> : IEnumerable<T>, IEnumerable
{
    int Count { get; }
}

열거자를 상속받기 때문에 foreach 루프를 통해서 요소를 참조하는 것이 가능하다. 그렇다면 해당 인터페이스의 용도는 무엇인가? 주로 컨테이너가 변하면 안되는 상황들에서 많이 쓰이는데, 예를 들어 동시성을 다룰 때가 될 수 있다. 혹은 Dictionary 컨테이너의 키 혹은 밸류 값 컨테이너를 반환 할 때가 될 수도 있다.

그리고 제네릭에서 눈에 띄는 점이 1가지가 있다. 바로 제네릭에 out 키워드가 붙었다. 제네릭에 out 이 붙었다면 이는 어떤 의미일까? 이는 공변성과 반공변성과 관련이 있다.

Covariance and Contravariance


공변성과 반공변성. 기본적으로 MSDN에서는 다음과 같이 정의한다.

📄 C#에서 공변성(Covariance)과 반공변성(Contravariance)은 배열 형식, 대리자 형식 및 제네릭 형식 인수에 대한 암시적 참조 변환을 가능하게 합니다. 공변성(Covariance)은 할당 호환성을 유지하고 반공변성(Contravariance)은 할당 호환성을 유지하지 않습니다.

보기만 해도 머리가 어질어질해진다. 컴퓨터 과학에서 다루는 엄밀한 정의가 아닌 프로그래머 입장에서 단순하게 다루어보도록 하겠다. 어렵게 생각할 것 없이 다음 예제부터 살펴보도록 하자.

IEnumerable<object> enumer = new List<object>();

열거가능한 객체로 object 리스트를 생성해주는 코드다. 여기까지는 크게 어려울 것 없이 이해가 가능 할 것이다. 그렇다면 다음 예시를 보도록 하자.

IEnumerable<object> enumer = new List<string>();

이 코드 또한 문제 없이 컴파일이 된다. 이는 가변성의 성질로 제네릭의 암묵적인 레퍼런스 변환(implict reference conversion)을 허용해주는 것이다. 가변성은 크게 공변성반공변성으로 나뉘는데, 위의 예시는 공변성에 해당한다. 아마 업 캐스팅 및 다운 캐스팅에 익숙한 사람들이 보기엔 당연해 보일지도 모른다. 그렇다면 다음 예시를 보도록 하자.

List<object> objects = new List<string>();

이 경우에는 컴파일 에러가 발생한다. 왜냐하면 콜렉션의 제네릭이 불변성이기 때문이다. 그래서 불변성, 가변성, 그리고 공변성과 반공변성은 다음과 같이 정리 할 수가 있다.

가변성과 불변성

  • 불변성 : 상, 하위 타입으로의 변환을 허용하지 않음
  • 가변성 : 상, 하위 타입으로의 변환을 허용함

공변성과 반공변성

  • 공변성 : 상위 타입으로의 레퍼런스 변환이 가능함
//covariance example
interface IVariable<out T>
  • 반공변성 : 하위타입으로의 레퍼런스 변환이 가능함
//cotravariance example
interface IVariable<in T>

Conclusion


읽기 전용 컨테이너의 인터페이스인 IReadOnlyCollection 에 대해서 살펴보았다. 본 컨테이너는 읽기 전용이긴 하지만 완전한 불변은 아니다. 단지 AddRemove 같은 메소드가 제공되지 않을 뿐이다. 불변성이 필요하다면 요소들의 값이 불변하는 ImmutableList 같은 컨테이너를 사용해야 한다. 개인적으로는 읽기 전용정도로도 충분하지 않을까 싶다.

Reference


C# 제네릭에서의 불변성과 가변성 - C# 프로그래밍 배우기 (Learn C# Programming)

profile
하늘을 향해 걸어가고 있습니다.

0개의 댓글