質問

EDIT: Maybe this is a clearer, more to the point formulation of the question:

In some generic interface IInterface<T>, I want to return an object of a generic type, where one of the type arguments should be an implementation of IInterface<T>.

public class OtherType<T> {}
public interface IInterface<T>
{
    OtherType<IInterface<T>> Operation();
}
public class Impl : IInterface<int>
{
    public OtherType<IInterface<int>> Operation()
    {
        return new OtherType<Impl>();
    }
}

Since Impl implements IInterface<int>, it seems reasonable to me that I could use it this way. Yet, it seems I cannot, I get the compiler error

Cannot convert expression type OtherType<Impl> to to return type OtherType<IInterface<int>>

役に立ちましたか?

解決

The issue is that OtherType<T> is a class and generic classes do not allow co/contravariance in C#. Generic interfaces do, as long as out types do not appear in any input positions, and in types do not appear in any output positions. In your code sample, you could get it to compile by introducing an additional interface marked covariant, and then altering your return type.

public interface IOtherType<out T> {} // new
public class OtherType<T> : IOtherType<T> { }

public interface IInterface<T>
{
    IOtherType<IInterface<T>> Operation(); // altered
}
public class Impl : IInterface<int>
{
    public IOtherType<IInterface<int>> Operation()
    {
        return new OtherType<Impl>();
    }
}

Whether or not this would actually fit your use case with your additional method definitions is something only you can know, given the limited about of detail in your code snippet.

他のヒント

OtherType<IInterface<int>> doesn't mean "implements" - it sort of means "is a type OtherType with a generic type parameter Interface<int>, but that isn't how you say it.

If you just want to make sure that the return type implements IInterface<int> then set that as the return type:

public interface IInterface<T>
{
    IInterface<T> Operation();
}

public class Impl : IInterface<int>
{
    public <IInterface<int>> Operation()
    {
        return new OtherType();
    }
}

where

public class OtherType : IInterface<int>
{}

This means you can return any type that implements IInterface<int>.

Otherwise you can make it a little more constrained on calling use a generic type constraint:

public interface IInterface<T>
{
    TRet Operation<TRet>() where TRet : IInterface<T>;
}

public class Impl : IInterface<int>
{
    public TRet Operation<TRet>() where TRet : IInterface<int>
    {
        return new OtherType();
    }
}

This means that you can constraint the operation to return a particular class, which has in turn to implement IInterface<int>.

It would be called:

Impl i = new Impl();
OtherType x = i.Operation<OtherType>();
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top