자바스크립트를 허용해주세요.
[ 자바스크립트 활성화 방법 ]
from Mohon Aktifkan Javascript!
 

[C#] 15장 제네릭 심화

728x90

✅ 1. where 제약조건

제네릭은 기본적으로 어떠한 타입이든 동작하나, 때때로 특정 기능을 보장해야할 때가 있습니다. 예를 들어 T가 반드시 선언한 값을 상속하고 기본 생성자가 있어야만 하고 싶다면 where 제약조건을 사용합니다.

public class Human
{
    public virtual void Speak() => Console.WriteLine("나는 인간이야");
}

public class Hungry : Human
{
    public override void Speak() => Console.WriteLine("나 배고파");
}

public class Sleep : Human
{
    public override void Speak() => Console.WriteLine("나 졸려");
}

// 제네릭 클래스에 제약 조건 추가
public class Action<T> where T : Human, new()
{
    public void MakeSound()
    {
        T human = new T(); // new() 연산자로 객체 생성 가능
        human.Speak(); // Human 제약 덕분에 Speak 호출 가능
    }
}
public class Where
{
    static void Main(string[] args)
    {
        var human1 = new Action<Hungry>();
        human1.MakeSound(); // 나 배고파

        var human2 = new Action<Sleep>();
        human2.MakeSound(); // 나 졸려
    }
}
  • where T : Human -> T는 반드시 Human이거나 하위 클래스여야 함
  • where T : new()  -> T는 반드시 public 기본 생성자를 가지고 있어야함

이러한 제약 덕분에 new T() 같은 코드를 구현할 수 있고, Human의 메서드(Speak)를 안전하게 호출할 수 있습니다.


✅ 2. 공변성 (Covariance, out)

공변성은 하위 타입을 상위 타입으로 변환할 수 있게 해주는 기능으로, IProducer<Sleep>IProducer<Hungry>로 쓸 수 있습니다. 

public class Human
{
    public virtual void Speak() => Console.WriteLine("나는 인간이야");
}

public class Hungry : Human
{
    public override void Speak() => Console.WriteLine("나 배고파");
}

public class Sleep : Human
{
    public override void Speak() => Console.WriteLine("나 졸려");
}

// 공변성(out) 
public interface IProducer<out T>
{
    T Produce();
}

// Hungry  생산
public class HungryProducer : IProducer<Hungry>
{
    public Hungry Produce() => new Hungry();
}

class Program
{
    static void Main()
    {
        Console.WriteLine("[공변성(out) 테스트]");

        IProducer<Hungry> hungryFactory = new HungryProducer();
        IProducer<Human> humanFactory = hungryFactory; // ✅ 공변성 덕분에 업스케일링 가능

        Human human = humanFactory.Produce();
        human.Speak(); // 나 배고파
    }
}
  • 키워드: out
  • 특징: 제네릭 타입이 출력 위치(리턴)에서만 사용 가능
  • 활용: 데이터를 만들어내는 생산자(Producer) 역할에 적합

✅ 3. 반공변성 (Contravariance, in)

반공변성은 상위 타입을 하위 타입으로 변환할 수 있겠 해주며, ICnsumer<Human>을 IConsumer<Hungry>로 쓸 수 있습니다.

public class Human
{
    public virtual void Speak() => Console.WriteLine("나는 인간이야");
}

public class Hungry : Human
{
    public override void Speak() => Console.WriteLine("나 배고파");
}

public class Sleep : Human
{
    public override void Speak() => Console.WriteLine("나 졸려");
}


// 반공변성(in) 인터페이스
public interface IConsumer<in T>
{
    void Consume(T item);
}

public class HumanConsumer : IConsumer<Human>
{
    public void Consume(Human a) => a.Speak();
}

class Program
{
    static void Main()
    {
        Console.WriteLine("[반공변성(in) 테스트]");

        IConsumer<Human> humanConsumer = new HumanConsumer();

        IConsumer<Hungry> hungryConsumer = humanConsumer;
        IConsumer<Sleep> sleepConsumer = humanConsumer;

        hungryConsumer.Consume(new Hungry()); // 출력: 나 배고파
        sleepConsumer.Consume(new Sleep()); // 출력: 나 졸려
    }
}

 ✅ 요약

  • where 제약조건은 제네릭 타입을 사용할 때 타입 매개변수에 조건을 강제 
  • 공변성 (out) -> 생산자(Producer) 개념으로 읽기 전용으로만 사용한다,  하위 -> 상위 변환 허용
  • 반공변성 (In) -> 소비자(Consumer) 개념으로 쓰기 전용으로만 사용. 상위 -> 하위 변환 허용

 

GitHub - Koras02/Csharp-posting: https://thinky.tistory.com/category/%EA%B2%8C%EC%9E%84%20%EB%AA%A8%EB%94%A9/C%23

https://thinky.tistory.com/category/%EA%B2%8C%EC%9E%84%20%EB%AA%A8%EB%94%A9/C%23 - Koras02/Csharp-posting

github.com

 

728x90
LIST