c# – 通用类型推理与多重实现的协变接口,如何解决?

前端之家收集整理的这篇文章主要介绍了c# – 通用类型推理与多重实现的协变接口,如何解决?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑这个愚蠢的程序,什么都不做:
  1. interface I<out T> { }
  2. class A1 : I<A1> { }
  3. class A2 : A1,I<A2> { }
  4. class B1 { }
  5. class B2 : B1,I<B2> { }
  6. class C1 : I<A1> { }
  7. class C2 : C1,I<A2> { }
  8.  
  9. static class Program
  10. {
  11. static void f<T>(I<T> obj)
  12. {
  13. }
  14.  
  15. static void Main()
  16. {
  17. f<A1>(new A2());
  18. f<A2>(new A2());
  19. f<B1>(new B2());
  20. f<B2>(new B2());
  21. f<A1>(new C2());
  22. f<A2>(new C2());
  23. }
  24. }

这表明,A2和C2实现了I< A1>和I A2,并且B2实现了两个I B1.和I B2.

但是,将其修改

  1. static void Main()
  2. {
  3. f(new A2());
  4. f(new B2());
  5. f(new C2());
  6. }

表示在第一行和第三行,f的泛型类型参数不能从传递的参数推断,但在第二行,它可以是.

我明白编译器在这里做什么,所以不需要解释.但是我该如何解决这个问题?有没有办法修改这个,以便我可以在基类和派生类上定义接口,但是在传递派生类时,还有类型推断工作?

我想到的是寻找一种方法来“隐藏”一个基类实现的接口,这样编译器就不会看到它们并使用它们,即使它们存在.但是,C#似乎没有提供这样的选择.

澄清:在我的愚蠢的示例程序中,A1将自己实现为通用类型参数.我确实有我的真实代码,但我也有类实现我与一个不同的通用类型的参数,并添加了C1和C2到我的示例代码为此原因.

解决方法

使用两个F变体(第二个仅用于调用另一个的类型推断)和“继承”接口J继承自I,它不会像这样做:
  1. using System;
  2. using System.Threading;
  3.  
  4.  
  5. interface I<out T>
  6. {
  7. void Print();
  8. }
  9.  
  10. interface J<out T> : I<T> { }
  11.  
  12. class A : I<C>
  13. {
  14. void I<C>.Print()
  15. {
  16. Console.WriteLine("A: I<C>");
  17. }
  18. }
  19.  
  20. class B {}
  21.  
  22. class C : B { }
  23.  
  24. class D1 : I<A>
  25. {
  26. void I<A>.Print()
  27. {
  28. Console.WriteLine("D1: I<A>");
  29. }
  30. }
  31.  
  32. class D2 : D1,J<B>
  33. {
  34. void I<B>.Print()
  35. {
  36. Console.WriteLine("D2: I<B>");
  37. }
  38. }
  39.  
  40. class D3 : D1,J<C>
  41. {
  42. void I<C>.Print()
  43. {
  44. Console.WriteLine("D3: I<C>");
  45. }
  46. }
  47.  
  48. class D4 : A,J<B>
  49. {
  50. void I<B>.Print()
  51. {
  52. Console.WriteLine("D4: I<B>");
  53. }
  54. }
  55.  
  56. static class Program
  57. {
  58. static void f<T>(J<T> obj)
  59. {
  60. f((I<T>)obj);
  61. }
  62.  
  63. static void f<T>(I<T> obj)
  64. {
  65. obj.Print();
  66. }
  67.  
  68. static void Main()
  69. {
  70.  
  71. f<A>(new D2());
  72. f(new D2());
  73.  
  74. f(new D3());
  75.  
  76. f(new D4());
  77. f<C>(new D4());
  78.  
  79. Console.ReadKey();
  80. }
  81. }

输出

  1. D1: I<A>
  2. D2: I<B>
  3. D3: I<C>
  4. D4: I<B>
  5. A: I<C>

猜你在找的C#相关文章