공변성(covariance)는 하위 클래스의 참조를 상위 클래스의 참조로 암시적으로 변환 시키는 것이다.
out 키워드를 사용하여 직접 공변 인터페이스 혹은 대리자를 정의할 수 있다.
string arrString = new string[10];
object[] arrObj = arrStr;
IEnumerable<string> lists = new List<string>();
IEnumerable<object> objs = lists;
public interface IProducer<out T>
{
T Produce(); // 반환만 가능 (매개변수로 사용 불가)
}
public class StringProducer : IProducer<string>
{
public string Produce() => "Hello!";
}
class Program
{
static void Main()
{
IProducer<string> stringProducer = new StringProducer();
IProducer<object> objectProducer = stringProducer;
object result = objectProducer.Produce();
Console.WriteLine(result);
}
}
반공변성(Contravariance)은 공변성과 반대로 상위 클래스의 참조를 하위 클래스의 참조로 암시적으로 변환 시키는 것이다.
in 키워드를 사용하여 직접 반공변 인터페이스 혹은 대리자를 정의할 수 있다.
static void Main(string[] args)
{
Action<object> delObj = CheckHash;
Action<string> a = (Action<object>)delObj;
a("Hello!");
}
static void CheckHash(object o)
{
Console.WriteLine(o.GetHashCode());
}
public interface IConsumer<in T>
{
void Consume(T item); // 입력만 가능 (반환 X)
}
public class ObjectConsumer : IConsumer<object>
{
public void Consume(object item)
{
Console.WriteLine("Consumed: " + item);
}
}
class Program
{
static void Main()
{
IConsumer<object> objConsumer = new ObjectConsumer();
IConsumer<string> stringConsumer = objConsumer;
stringConsumer.Consume("Hello!");
}
}