【问题标题】:Casting in Generics with related/derived Ts使用相关/派生的 Ts 在泛型中进行铸造
【发布时间】:2013-05-07 10:41:23
【问题描述】:
class BaseItem { }

class DerivedItem : BaseItem { }

interface IInterface<T> where T is BaseItem { }

class RealizedInterface<T> : IInterface<T> { }

RealizedInterface<BaseItem> rb;
RealizedInterface<DerivedItem> rd = new RealizedInterface<DerivedItem>;

有没有下一行所示的投射方式:

rb = rd;   

谁能告诉我如何将rd 转换为rb

其实BaseItem本身也是一个泛化类但是为了简单的问题,没有写。 class BaseItem&lt;U,K&gt; / DerivedItem&lt;U,K&gt;

对于那些能够理解我面临的真正问题的人来说是这样的。

IShape<IBaseShape<long>, long> shape;

这是一个声明的对象

IShape<ITriangle<long>, long> triangle =new Shape<ITriangle<long>,long>(); //Shape derived from IShape

shape = triangle; //here is the problem.

其中 ITriangle 派生自 IBaseShape。非常感谢任何帮助。

结果:我决定不实施 out 关键字。就我而言,它并没有带来太多价值(这是一个持续数月的项目,到处都是仿制药)。具体来说,如果您考虑在具有 in 关键字的接口中实现 setter 并使用 out 关键字实现 getter,再加上在装饰有 out 关键字的接口中使用泛型所产生的转换问题让我想到关于它两次。总而言之,如果您从头开始使用它们可能会很有用,否则可能会带来比您想象的更多的问题。

【问题讨论】:

  • 语言将是一个有用的附加标签。此外,如果您想发布代码示例,通常最好突出显示代码并点击{} 按钮。

标签: c# generics casting


【解决方案1】:

您正在寻找的是泛型类型的协变和逆变。您可以阅读主题here

【讨论】:

    【解决方案2】:

    如果IShape 的定义方式是您只“检索”第一个类型参数的元素,则将您的定义从IShape&lt;T, U&gt; 更改为IShape&lt;out T, U&gt; 以告诉编译器这一点,然后一切都会正常工作(给定足够新的 .NET 版本)。

    如果IShape 的定义方式是您可以通过接口“推送”第一个类型参数in 的元素,那么这个不能 起作用。如果您将IShape&lt;ITriangle...&gt; 隐藏为IShape&lt;IBaseShape...&gt;,那么如果您尝试将ISquare“推入”其中,它将中断。

    【讨论】:

      【解决方案3】:

      只要您继续使用接口而不是实际的类,就可以使用协变/逆变。

      像这样:

      void Main() {   
          RealizedInterface<BaseItem> rb1;
          RealizedInterface<DerivedItem> rd1 = new RealizedInterface<DerivedItem>();
          rb1 = rd1; // doesn't work
      
          IInterface<BaseItem> rb2;
          IInterface<DerivedItem> rd2 = new RealizedInterface<DerivedItem>();
          rb2 = rd2; // works
      }
      
      // Define other methods and classes here
      class BaseItem { }
      
      class DerivedItem : BaseItem { }
      
      interface IInterface<out T> where T:  BaseItem { } // Notice the out keyword!
      
      class RealizedInterface<T> : IInterface<T> where T:BaseItem { }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-13
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多