泛型,协方差/协方差等 [英] Generics, Covariance/Contravariance, etc

查看:58
本文介绍了泛型,协方差/协方差等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我有一些Java代码可以广泛使用编译正常的泛型.我将其移植到C#,如下所示:

So I have some Java code that makes extensive use of generics that compiles just fine. I ported it over to C# as follows:

interface IFoo1 { }
interface IFoo2 { }

interface IBar<T, K>
    where T : IFoo1
    where K : IFoo2 {
    List<T> GetFoo1s();
    void AddAFoo1(T foo1);

    List<K> GetFoo2s();
    void AddAFoo2(K foo2);
}

interface IBlip<T>
    where T : IBar<IFoo1, IFoo2> {
    T DoBlip(string input);
    void DoBlip2(T input);
}

interface IConverter<T, K>
    where T : IBar<IFoo1, IFoo2>
    where K : IBar<IFoo1, IFoo2> {
    K Convert(T input);
}

class FooA1 : IFoo1 { }
class FooB1 : IFoo1 { }

class FooA2 : IFoo2 { }
class FooB2 : IFoo2 { }

class BarA : IBar<FooA1, FooA2> {
    public List<FooA1> GetFoo1s() { return null;  }
    public void AddAFoo1(FooA1 foo1) { }
    public List<FooA2> GetFoo2s() { return null; }
    public void AddAFoo2(FooA2 foo2) { }
}

class BarB : IBar<FooB1, FooB2> {
    public List<FooB1> GetFoo1s() { return null; }
    public void AddAFoo1(FooB1 foo1) { }
    public List<FooB2> GetFoo2s() { return null; }
    public void AddAFoo2(FooB2 foo2) { }
}

class BlipA : IBlip<BarA> {
    public BarA DoBlip(string input) { return null; }
    public void DoBlip2(BarA input) { }
}

class BlipB : IBlip<BarB> {
    public BarB DoBlip(string input) { return null; }
    public void DoBlip2(BarB input) { }
}

class ConverterImplementation : IConverter<BarA, BarB> {
    public BarB Convert(BarA input) {
        return null;
    }
}

当我对此进行编译时,它抱怨说,例如,使用ConverterImplementation,BarA无法隐式转换为IBar.我猜这里根本没有我想要的东西.有人可以阐明一下吗?谢谢.

When I compile this, it complains that, for example, with the ConverterImplementation, that BarA cannot be implicitly converted to IBar. I guess there's something that I'm fundamentally missing here. Could someone shed some light on it? Thanks.

推荐答案

默认情况下,通用类型参数既不是协变也不是协变,但可以通过"in"和"out"关键字使它们成为一个或另一个.

Generic type parameters are by default neither contravariant nor covariant, but can be made one or the other via the "in" and "out" keywords.

在IBar< T,K>的情况下,两个类型参数都用作输入和输出,因此您不能使它们成为协变或协变的.如果将其重构为两个接口,一个在其中T仅用于输入而K仅用于输出,而在其中T仅用于输出而K仅用于输入的接口,则可以使每个类型参数基于协变或互变

In the case of IBar<T, K>, both type parameters are used as both inputs and outputs, so you cannot make them either contravariant or covariant. If you refactored it into two interfaces, one in which T is used only for input and K only for output, and one in which T is used only for output and K only for input, then you could make each type parameter covariant or contravariant based on its usage.

这篇关于泛型,协方差/协方差等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆