简体   繁体   中英

C# Covariance in generic types

I can not get around C# covariance for this simple example, here is how I defined my model:

interface IResponse { }
interface ICommand<out TResponse> where TResponse : IResponse { }
class Response : IResponse { }
class Command<TResponse> : ICommand<TResponse> where TResponse : IResponse { }

So I can use it like this

IResponse rsp = new Response(); //Works, obviously!
ICommand<IResponse> cmdi = new Command<Response>(); //Works, but I don't need this 
Command<IResponse> cmd = new Command<Response>(); //Compile time error! :(

The Command in Command<TResponse> doesn't even has any property or method of TResponse type. How can I change it so it works?

Your compile time problem occurs, because you declared Command so that it can only receive a TResponse, not an IResponse.

Consider improving your code, instead of

class Command<TResponse>

use

class Command<IResponse>. 

Command will now work with any TResponseXYZ type that implement IResponse, like you intend. To make sure that Command methods can access all relevant properties of TResponseXYZ types, you should publish them as public properties in TResponseXYZ and use the IResponse interface to declare them as get;set; properties. Worked out example:

interface ICommand<out TResponse> where TResponse : IResponse { }

public interface IResponse
{
    int MyField { get; set; }
}

public class TResponseA : IResponse
{
    public int MyField { get; set; }
}

public class TResponseB : IResponse
{
    public int MyField { get; set; }
}

public class Command<TResponse> : ICommand<TResponse> where TResponse : IResponse
{
    public Command(IResponse R)
    {
        // here you can access R.MyField=17 using R.MyField
    }

    public static void Test()
    {
        var rA = new TResponseA() { MyField = 17 };
        var cmdA = new Command<TResponseA>(rA);

        var rB = new TResponseB() { MyField = 17 };
        var cmdB = new Command<TResponseB>(rB);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM