从专用类型强制转换为其泛型接口



只要我们谈论动物和鱼类,协方差和逆变就很清楚了,但是为什么这行不通,你能给我解释一下吗?

interface IType
{}
interface IGenericInterface<TType> where TType:IType
{}
class TypeImpl:IType
{}
class GenericTypeImpl : IGenericInterface<TypeImpl>
{}
class Program
{
    static void Main(string[] args)
    {
        Convert<IGenericInterface<TypeImpl>, TypeImpl>(new GenericTypeImpl());
    }
    static IGenericInterface<IType> Convert<S, D> (S instance) where S:IGenericInterface<D> where D:IType
    {
        return (IGenericInterface<IType>)instance; //nope
    }
}

确实我可以用出来解决演员表,但是我不能这样做:

interface IGenericInterface<out TType> where TType:IType
    {
        void afunction(TType type); //nope
        void afunction(IType type); //works but not nice
    }

编辑:没有解决方法。我感兴趣的原因是(在放弃之前(是我想将所有GenericTypeImpl实例收集到一个集合中,然后通过泛型函数使用。显然,在集合中存储 IType 实现可能不同的IGenericInterface<IType>实现的唯一方法是使用 IGenericInterface<IType> 作为集合参数,所以我需要将单个实例强制转换为原始类型并调用方法 afunction ,代码类似于:

void CallSuitableAFunction<T>(T type) where T : IType
{
    if (_collectedInstances.TryGetValue(typeof(T), out instance))
    {
         (instance as IGenericInterface<T>).afunction(); //will throw
    }
}
Dictionary<Type, IGenericInterface<IType>> _collectedInstances;

在你的类型实现中没有协方差和逆变。 您应该将 out 用于协方差(这是您的情况(,或将 in 用于逆变。

interface IGenericInterface<out TType> where TType:IType // notice out keyword
{}

当你制作协方差TType它应该只用作输出,例如仅在方法的返回类型中,如TType Method()或仅作为 out 参数void Method(out TType),此方法void Method(TType)具有 TType 的输入,因此由于规则,它与协方差不兼容(编译器规则基本上是为了类型安全(。

您可以通过实现另一个不包含该方法的接口来解决此问题,您将从该接口失去对该方法的访问权限(您需要强制转换(。

interface IGenericInterfaceCovariant<out TType> where TType:IType
{
    // don't use TType as input        
    void afunction(IType type); // `IType` is still valid though since its interface. notice the "I" and "T" differences before "Type"
}
interface IGenericInterface<TType> : IGenericInterfaceCovariant<TType> where TType:IType
{ 
   void afunction(TType type);
}

然后你可以这样投射。

return (IGenericInterfaceCovariant<IType>)instance;

最新更新