相关疑难解决方法(0)

通用类型参数协方差和多个接口实现

如果我有一个带有协变类型参数的泛型接口,如下所示:

interface IGeneric<out T>
{
    string GetName();
}
Run Code Online (Sandbox Code Playgroud)

如果我定义这个类层次结构:

class Base {}
class Derived1 : Base{}
class Derived2 : Base{}
Run Code Online (Sandbox Code Playgroud)

然后我可以使用显式接口实现在单个类上实现两次接口,如下所示:

class DoubleDown: IGeneric<Derived1>, IGeneric<Derived2>
{
   string IGeneric<Derived1>.GetName()
   {
     return "Derived1";
   }

   string IGeneric<Derived2>.GetName()
   {
     return "Derived2";
   }  
}
Run Code Online (Sandbox Code Playgroud)

如果我使用(非泛型)DoubleDown类并将其强制转换为IGeneric<Derived1>IGeneric<Derived2>按预期运行:

var x = new DoubleDown();
IGeneric<Derived1> id1 = x;        //cast to IGeneric<Derived1>
Console.WriteLine(id1.GetName());  //Derived1
IGeneric<Derived2> id2 = x;        //cast to IGeneric<Derived2>
Console.WriteLine(id2.GetName());  //Derived2
Run Code Online (Sandbox Code Playgroud)

但是,转换xIGeneric<Base>,给出以下结果:

IGeneric<Base> b = x;
Console.WriteLine(b.GetName());   //Derived1 …
Run Code Online (Sandbox Code Playgroud)

c# generics types interface covariance

44
推荐指数
4
解决办法
2977
查看次数

如何找到两种类型之间最佳拟合的最小协变类型?

IsAssignableFrom方法返回一个布尔值,表示一种类型是否可以从另一种类型分配.

怎能不只有他们分配的测试对方,但也知道了最低协变,以获得最佳类型?

考虑以下示例(C#4.0)

  • // method body of Func is irrelevant, use default() instead
    Func<char[]> x = default(Func<char[]>);
    Func<int[]> y = default(Func<int[]>);
    
    Func<Array> f = default(Func<Array>);
    Func<IList> g = default(Func<IList>);
    
    g=x;
    g=y;
    
    y=x; // won't compile
    x=y; // won't compile
    
    // following two are okay; Array is the type for the covariance
    f=x; // Array > char[] -> Func<Array> > Func<char[]> 
    f=y; // Array > int[] -> Func<Array> > Func<int[]> 
    
    // following …
    Run Code Online (Sandbox Code Playgroud)

c# types covariance contravariance

21
推荐指数
1
解决办法
1201
查看次数

为什么vb.net拒绝将嵌套协变接口赋值为"模糊"

在代码中:

Interface ISelf(Of Out TMe)
End Interface
Class SomeBase
    Implements ISelf(Of SomeBase)
End Class
Class SomeDerived
    Inherits SomeBase
    Implements ISelf(Of SomeDerived)
End Class
Module ISelfTester
    Sub TestISelf()
        Dim z7 As New SomeDerived
        Dim z8 As ISelf(Of SomeDerived)
        Dim z9 As ISelf(Of ISelf(Of SomeDerived))
        z8 = z7
        z9 = z8
        z9 = z7 ' Why is this illegal?
    End Sub
End Module
Run Code Online (Sandbox Code Playgroud)

直接从Z7到Z9的赋值产生消息"错误13选项Strict On不允许从'wokka.SomeDerived'到'wokka.ISelf(Of Wokka.SomeDerived))的隐式转换',因为转换是模糊的".那个分配怎么比Z7到Z8,或Z8到Z9的分配更模糊?据我所知,所有三个赋值必须是表示保留转换,这意味着所有三个都必须简单地存储与Z7相同的对象的引用.

我能理解,如果我试图实例分配SomeDerived给类型的引用ISelf(Of ISelf(Of SomeBase)),试图访问该接口的成员可以从任一得到实施SomeBaseSomeDerived; 如果成员是一个返回类型的方法TMe,我可以理解这种歧义可能导致编译失败(因为编译器不知道返回类型是什么).但是,我很困惑,为什么仅仅因为"模糊性"而仅仅尝试分配引用失败,因为赋值不能被解释为除了直接存储对引用类型变量的引用之外的任何东西?

顺便说一句,预期的用法是ISelf(Of …

vb.net compiler-errors ambiguity covariance

5
推荐指数
1
解决办法
211
查看次数