본문 바로가기
프로그래밍/C#

C# 공변성(Covariance)이란 무엇인가?

by bantomak 2024. 3. 26.

공변성

공변성은 대리자에서 정의하고 있는 반환 형식보다 하위의 상속 형식(서브 형식, 더 많이 상속된 형식) 반환을 허용한다.

 

Covariance 프로젝트에서 대리자의 공변성 예제를 살펴보자. 

public partial class Program
{
    private delegate TextWriter CovarianceDelegate();
}

 

이 대리자는 TextWriter 형식을 반환한다. 다음으로 StreamWriterMethod()를 만들 텐데, 이 메서드는 StreamWriter 개체를 반환한다.

 

public partial class Program
{
    private static StreamWriter StreamWriterMethod()
    {
        DirectoryInfo[] arrDirs = new DirectoryInfo(@"C:\Windows").GetDirectories("s*", SearchOption.TopDirectoryOnly);

        StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());

        foreach(DirectoryInfo dir in arrDirs)
        {
            sw.WriteLine(dir.Name);
        }

        return sw;
    }
}

 

StringWriter 개체를 반환하는 STringWriterMethod() 메서드도 다음과 같이 생성한다.

 

private static StringWriter StringWriterMethod()
{
    StringWriter strWriter = new StringWriter();

    string[] arrString = new string[]
    {
        "Covariance",
        "example",
        "using",
        "StringWriter",
        "object"
    };

    foreach (string str in arrString)
    {
        strWriter.Write(str);
        strWriter.Write(' ');
    }

    return strWriter;
}

 

보다시피 이들은 StreamWriter와 STringWriter라는 서로 다른 개체를 반환하며, 이 형식들은 CovarianceDelegate 대리자의 반환 형식인 TextWriter와도 다르다. 하지만 StreamWriter와 StringWriter는 TextWriter를 상속하고 있기 때문에 대리자의 공변성에 따라 이 메서드들은 CovarianceDelegate 대리자에 할당할수 있다. (두둥!)

 

StreamWriterMethod()를 CovarianceDelegate 대리자에 할당하는 과정은 CovarianceStreamWriterInvoke() 메서드에서 구현하고 있다.

 

private static void CovarianceStreamWirterInvoke()
{
    CovarianceDelegate covDelegate;
    Console.WriteLine("Invoking CovarianceStreamWriterInvoke Method:");
    covDelegate = StreamWriterMethod;

    StreamWriter sw = (StreamWriter)covDelegate();
    sw.AutoFlush = true;
    Console.SetOut(sw);
}

 

다음은 CovarianceStreamWriterInvoke() 메서드의 실행 결과다.

 

 

예제는 VisualStudio 2022 설치 경로에 포함된 디렉터리 리스트를 출력하고 있는데, 설치된 버전에 따라 경로의 차이는 있을 수 있다.

 

자, 이번에는 CovarianceDelegate 대리자를 이용해서 StringWriterMethod()를 호출해 보겠다. 이를 위해 다음과 같이 CovarianceStringWriterInvoke() 메서드를 구현한다.

 

private static void CovarianceStringWirterInvoke()
{
    CovarianceDelegate covDelegate;
    Console.WriteLine("Invoking CovarianceStreamWriterInvoke Method:");
    covDelegate = StringWriterMethod;

    StringWriter strW = (StringWriter)covDelegate();
    Console.WriteLine(strW.ToString());
}

 

 

지금까지 대리자의 공변성을 예제를 통해 증명했다. 공변성에 따라 TextWriter 를 반환하는 CovarianceDelegate 대리자는 StreamWriter나 StringWriter를 반환하는 메서드를 참조할 수 있다. 다음 코드는 앞서 살펴본 예제에서 추출한 것으로 대리자의 공변성을 여실히 보여준다.

 

private delegate TextWriter CovarianceDelegate();
CovarianceDelegate covDelegate;
covDelegate = StreamWriterMethod();
covDelegate = StringWriterMethod();

 

함께 읽으면 좋은 글

 

Effective C# Item 22 : 공변성과 반공변성을 지원하라

공변성(Convariance)과 반공변성(Contravariance)을 지원하라 타입의 가변성(Variance), 즉 공변(Covariance)과 반공변(Contravariance)은 특정 타입의 객체를 다른 타입의 객체로 변환할 수 있는 성격을 일컫는다.

jettstream.tistory.com

댓글