English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# 변환과逆变

변환과逆变은 클래스 계층을 처리할 때 더 유연하게 합니다.

변환과逆变에 대해 배우기 전에 다음 클래스 계층을 보세요:

public class Small
{ 
}
public class Big: Small
{
}
public class Bigger : Big
{ 
    
}

위의 예제 클래스에 따르면, Small은 Big의 기본 클래스이고, Big은 Bigger의 기본 클래스입니다. 기억해야 할 것은 파생 클래스는 항상 기본 클래스보다 더 많은 것이 있기 때문에 기본 클래스는 파생 클래스보다 작습니다.

지금, 다음 초기화를 보겠습니다:

클래스 초기화

위와 같이 기본 클래스는 파생 클래스를 포함할 수 있지만, 파생 클래스는 기본 클래스를 포함할 수 없습니다. 다시 말해, 인스턴스는 작은 것을 요구하더라도 큰 것을 받아들일 수 있지만, 큰 것을 요구하면 작은 것을 받아들일 수 없습니다.

지금, 변환과逆变에 대해 이해해보겠습니다.

C# 변환(Covariance)

변환은 기본 유형이 필요한 파생 유형을 전달할 수 있게 합니다. 변환은 동일 유형의 차이와 같습니다. 기본 클래스와 파생 클래스는 기본 유형에 추가 기능을 제공하는 동일 유형의 클래스로 간주됩니다. 따라서 변환은 기본 클래스가 필요할 때 파생 클래스를 사용할 수 있게 합니다(소형이 필요하면 큰형을 받아들일 수 있는 경우, rule: 큰형을 받아들일 수 있습니다).

Covariance는 대리자, 일반화, 배열, 인터페이스 등에 적용될 수 있습니다.

대리자 변이

대리자의 변이는 대리자 메서드의 반환 타입이 유연성을 가질 수 있도록 허용합니다.

public delegate Small covarDel(Big mc);
public class Program
{
    public static Big Method1(Big bg)
    {
        Console.WriteLine("Method1");
    
        return new Big();
    }
    public static Small Method2(Big bg)
    {
        Console.WriteLine("Method2");
    
        return new Small();
    }
        
    public static void Main(string[] args)
    {
        covarDel del = Method1;
        Small sm1 = del(new Big());
        del = Method2;
        Small sm2 = del(new Big());
    }
}
출력:
메서드1
메서드2

위 예제에서 볼 수 있듯이, 대리자는 Small(기본 클래스)을 반환하는 타입을 기대하지만, 여전히 Big(파생 클래스)을 반환하는 Method을 할당할 수 있습니다.1또한 대리자가 기대하는签名와 동일한 Method2.

따라서 Covariance는 적은 파생 클래스 반환 타입을 가진 대리자에 메서드를 할당할 수 있도록 허용합니다.

C# 역변 (Contravariance)

Contravariance(역변)를 매개변수에 적용. Contravariance(역변)는 기본 클래스 매개변수를 파생 클래스 매개변수를 기대하는 대리자의 메서드에 할당할 수 있음.

위 예제를 계속하며, 대리자와 다른 매개변수 타입을 가진 Method 추가3:

delegate Small covarDel(Big mc);
class Program
{
    static Big Method1(Big bg)
    {
        Console.WriteLine("Method1");
        return new Big();
    }
    static Small Method2(Big bg)
    {
        Console.WriteLine("Method2");
        return new Small();
    }
    static Small Method3(Small sml)
    {
        Console.WriteLine("Method3");
        
        return new Small();
    }
    static void Main(string[] args)
    {
        covarDel del = Method1;
        del += Method2;
        del += Method3;
        Small sm = del(new Big());
}
출력:
메서드1
메서드2
메서드3

그러나如您 본 것처럼, Method3Small 클래스의 매개변수를 가진 파라미터가 있으며 대리자는 Big 클래스의 매개변수를 기대합니다. 그러나 Method3대리자와 함께 사용.

위와 같은 방법으로 변이와 역변을 사용할 수 있습니다.

예제: 변이와 역변의 사용
delegate Small covarDel(Big mc); class Program
{    static Big Method}}4(Small sml)
    {        Console.WriteLine("Method3");    
        return new Big();
    }
    {        covarDel del = Method4;    
        Small sm = del(new Big());
    }
}
출력:
메서드4