覆盖返回泛型类的方法

本文关键字:方法 泛型类 返回 覆盖 | 更新日期: 2023-09-27 18:16:28

在我的Silverlight 4应用程序中,我开始创建和使用一些泛型,现在我偶然发现了以下问题:

在非泛型类中,我有一个抽象方法,它返回一个泛型类:

public abstract class DTO_Base()
{
  public abstract ServiceModelBase<ServiceNodeBase> CreateBusinessObject();
}

泛型类定义如下:

public abstract class ServiceModelBase<RootNodeType> where RootNodeType : ServiceNodeBase

当然,从DTO_Base派生的类必须重写CreateBusinessObject方法:

public class DTO_Editor : DTO_Base
{
  public override ServiceModelBase<ServiceNodeBase> CreateBusinessObject()
  {
    // the object to return have to be of type ServiceModelEditor
    // which is derived from ServiceModelBase<ServiceNodeEditor>
    // public class ServiceModelEditor : ServiceModelBase<ServiceNodeEditor>
    // ServiceNodeEditor is derived from ServiceNodeBase
    // public class ServiceNodeEditor : ServiceNodeBase
    ServiceModelEditor target = new ServiceModelEditor()
    ...
    Functions to populate the 'target'
    ...
    return target;
  }
}

返回target;行导致错误,指出不可能隐式地转换ServiceModelBase<ServiceNodeBase>中的ServiceModelEditor类型。此外,通过目标显式转换为ServiceModelBase<ServiceNodeBase>不起作用。

我要如何实现这个方法的工作?

覆盖返回泛型类的方法

试试这个:

public interface IDTO<Node> where Node : ServiceNodeBase
{
    ServiceModelBase<Node> CreateBusinessObject();
}
public abstract class DTO_Base<Model,Node> : IDTO<Node>
    where Model : ServiceModelBase<Node>
    where Node : ServiceNodeBase
{
    public abstract Model CreateBusinessObject();

    #region IDTO<Node> Members
    ServiceModelBase<Node> IDTO<Node>.CreateBusinessObject()
    {
        return CreateBusinessObject();
    }
    #endregion
}
public class DTO_Editor : DTO_Base<ServiceModelEditor, ServiceNodeEditor>
{
    public override ServiceModelEditor CreateBusinessObject()
    {
        // the object to return have to be of type ServiceModelEditor
        // which is derived from ServiceModelBase<ServiceNodeEditor>
        // public class ServiceModelEditor : ServiceModelBase<ServiceNodeEditor>
        // ServiceNodeEditor is derived from ServiceNodeBase
        // public class ServiceNodeEditor : ServiceNodeBase
        ServiceModelEditor target = new ServiceModelEditor();

        return target;
    }
}

我以前遇到过类似的问题,唯一合理的做法是使核心基类也泛型。您可以删除Model通用参数(和接口),这样看起来就不那么可怕了,但是您可以在方法之外看到ServiceModelEditor的功能。

事实上,您已经返回ServiceModelBase<ServiceNodeBase>。一种选择是使基类泛型:

public abstract class DtoBase<T> where T : RootNodeType
{
    public abstract ServiceModelBase<T> CreateBusinessObject();
}

:

public class DtoEditor : DtoBase<ServiceNodeBase>
{
    public override ServiceModelBase<ServiceNodeBase> CreateBusinessObject()
    {
        ...
    }
}

如果您正在使用。net 4.0,我建议您使用接口来定义您的ServiceModelBase,并在该接口泛型上指定out方差修饰符:

class ServiceNodeBase { }
class ServiceNodeEditor : ServiceNodeBase {/*implementation*/}
//
interface IServiceModelBase<out RootNodeType>
    where RootNodeType : ServiceNodeBase { 
}
class ServiceModelEditor : IServiceModelBase<ServiceNodeEditor> {
    /*implementation*/
}
//
abstract class DTO_Base {
    public abstract IServiceModelBase<ServiceNodeBase> CreateBusinessObject();
}
class DTO_Editor : DTO_Base {
    public override IServiceModelBase<ServiceNodeBase> CreateBusinessObject() {
        return new ServiceModelEditor();
    }
}