interface I<out T> { }class A1 : I<A1> { }class A2 : A1,I<A2> { }class B1 { }class B2 : B1,I<B2> { }class C1 : I<A1> { }class C2 : C1,I<A2> { }static class Program{ static voID f<T>(I<T> obj) { } static voID Main() { f<A1>(new A2()); f<A2>(new A2()); f<B1>(new B2()); f<B2>(new B2()); f<A1>(new C2()); f<A2>(new C2()); }}@H_404_4@这表明,A2和C2实现了I< A1>和I A2,并且B2实现了两个I B1.和I B2. @H_404_4@但是,将其修改为
static voID Main(){ f(new A2()); f(new B2()); f(new C2());}@H_404_4@表示在第一行和第三行,f的泛型类型参数不能从传递的参数推断,但在第二行,它可以是. @H_404_4@我明白编译器在这里做什么,所以不需要解释.但是我该如何解决这个问题?有没有办法修改这个,以便我可以在基类和派生类上定义接口,但是在传递派生类时,还有类型推断工作? @H_404_4@我想到的是寻找一种方法来“隐藏”一个基类实现的接口,这样编译器就不会看到它们并使用它们,即使它们存在.但是,C#似乎没有提供这样的选择. @H_404_4@澄清:在我的愚蠢的示例程序中,A1将自己实现为通用类型参数.我确实有我的真实代码,但我也有类实现我与一个不同的通用类型的参数,并添加了C1和C2到我的示例代码为此原因.解决方法 使用两个F变体(第二个仅用于调用另一个的类型推断)和“继承”接口J继承自I,它不会像这样做:
using System;using System.Threading;interface I<out T>{ voID Print();}interface J<out T> : I<T> { }class A : I<C>{ voID I<C>.Print() { Console.Writeline("A: I<C>"); }}class B {}class C : B { }class D1 : I<A>{ voID I<A>.Print() { Console.Writeline("D1: I<A>"); }}class D2 : D1,J<B>{ voID I<B>.Print() { Console.Writeline("D2: I<B>"); }}class D3 : D1,J<C>{ voID I<C>.Print() { Console.Writeline("D3: I<C>"); }}class D4 : A,J<B>{ voID I<B>.Print() { Console.Writeline("D4: I<B>"); }}static class Program{ static voID f<T>(J<T> obj) { f((I<T>)obj); } static voID f<T>(I<T> obj) { obj.Print(); } static voID Main() { f<A>(new D2()); f(new D2()); f(new D3()); f(new D4()); f<C>(new D4()); Console.ReadKey(); }}@H_404_4@输出:
D1: I<A>D2: I<B>D3: I<C>D4: I<B>A: I<C>总结
以上是内存溢出为你收集整理的c# – 通用类型推理与多重实现的协变接口,如何解决?全部内容,希望文章能够帮你解决c# – 通用类型推理与多重实现的协变接口,如何解决?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)