实现Co和Contra方差通用接口&它的实际用途

时间:2011-02-22 13:02:50

标签: c# covariance contravariance

我试图了解使用变体通用接口的可能用法(使用co和contra变体)。有人可以解释一下吗?我理解了各个接口的co和contra方差示例,

协方差示例

public class Request { }
public class Response { }
public class SuperRequest : Request { }
public class SuperResponse : Response { }

public interface CoVarianceInterface<out O>
{
    O Get();
}

public class CoVarianceInterfaceInstance1 : CoVarianceInterface<Response>
{
    public Response Get()
    {
        Console.WriteLine("Co Variance");

        return null;
    }
}

public class CoVarianceInterfaceInstance2 : CoVarianceInterface<SuperResponse>
{
    public SuperResponse Get()
    {
        Console.WriteLine("Co Variance 1");

        return null;
    }
}

static void CallCoVarianceInterface(CoVarianceInterface<Response> task)
{
    task.Get();
}

static void Test()
{
   CoVarianceInterface<Response> i1 = new CoVarianceInterfaceInstance1();
   CoVarianceInterface<SuperResponse> i2 = new CoVarianceInterfaceInstance2();

   CallCoVarianceInterface(i1);
   CallCoVarianceInterface(i2); **//Co variance here bcoz more derived to less derived type?**
}

Contra方差示例

public interface ContraVarianceInterface<in O>
{
    void Set(O input);
}

public class ContraVarianceInterfaceInstance1 : ContraVarianceInterface<Request>
{
    public void Set(Request input)
    {
        Console.WriteLine("Contra Variance");
    }
}

public class ContraVarianceInterfaceInstance2 : ContraVarianceInterface<SuperRequest>
{
    public void Set(SuperRequest input)
    {
        Console.WriteLine("Contra Variance 1");
    }
}

static void CallContraVarianceInterface(ContraVarianceInterface<SuperRequest> task)
{
    task.Set(null);
}

static void Test()
{
  ContraVarianceInterface<Request> o1 = new ContraVarianceInterfaceInstance1();
  ContraVarianceInterface<SuperRequest> o2 = new ContraVarianceInterfaceInstance2();

  CallContraVarianceInterface(o1); **//Contra variance here bcoz less derived to more derived type?**
  CallContraVarianceInterface(o2);
}

Co / Contra差异

public interface CoContraInterface<out O, in I>
{
    O Execute(I input);
}

public class CoContraInterfaceInstance1 : CoContraInterface<Response, Request>
{
    public Response Execute(Request input)
    {
        Console.WriteLine("Variance");

        return new Response();
    }
}

public class CoContraInterfaceInstance2 : CoContraInterface<SuperResponse, SuperRequest>
{
    public SuperResponse Execute(SuperRequest input)
    {
        Console.WriteLine("Variance 1");

        return new SuperResponse();
    }
}

static void CallCoContraInterface(CoContraInterface<Request, Response> task)
{
    task.Execute(null);
}

static void Test()
{
   CoContraInterface<Response, Request> c1 = new CoContraInterfaceInstance1();
   CoContraInterface<SuperResponse, SuperRequest> c2 = new CoContraInterfaceInstance2();
   CoContraInterface<Response, SuperRequest> c3 = new CoContraInterfaceInstance1();

   c3 = c1; **//here Request is typed to SuperRequest, so is it contra variance?**
   c3 = c2; **//here Request is typed to SuperRequest, so is it contra variance? also SuperResponse to Response, so is it Co variance as well?**

  CreateSample(c1);
  CreateSample(c2);
  CreateSample(c3);
}


is the above code right? if so where we can practically use an interface that have both Co and Contra variance?

由于