【问题标题】:Return a subclass of abstract return type?返回抽象返回类型的子类?
【发布时间】:2014-11-10 21:57:30
【问题描述】:

我的项目结构如下:

// Abstract class
public abstract class Job
{
    public abstract JobResult Run();
}
public abstract class JobResult { }

// Concrete implementer
public class Job1 : Job
{
    public override Job1Result Run() { }
}
public class Job1Result : JobResult { }

每个具体的作业都继承自 Job 并实现方法 Run 返回一个具体的 JobResult 类。

但是,当我这样做时,我得到了编译器错误:

Job1.Run()':返回类型必须是 JobResult 才能匹配被覆盖的成员 Job.Run()

重写抽象方法时,真的不能返回返回类型的继承对象吗?

【问题讨论】:

  • 试试改成public override Job1Result Run() ?
  • @McAdam331 对不起,我在我的项目中有这个,但忘记在我的问题中包含它。我已经更新它以包含它。但仍然出现错误。
  • 这称为返回类型协方差。不支持。覆盖必须匹配签名、通用约束、返回类型。

标签: c# inheritance


【解决方案1】:

这就是继承的全部概念。返回父类在这里被认为是一个特性。然而,没有什么能阻止你在 Job1 中返回 Job1Result

public JobResult Run()
{
  return new Job1Result();
}

然后 Job1.Run() 的调用者必须知道正确的返回类型并将其转换为访问特定于该类的 Job1Result 方法

【讨论】:

  • 但是您需要始终将返回值从 JobResult 转换为 Job1result
  • 如果您不需要从 Job1Result 访问任何特殊内容,则不需要
【解决方案2】:

你可以让Jobgeneric:

public abstract class Job<TResult> where TResult : JobResult
{
    public abstract TResult Run();
}

public class Job1 : Job<Job1Result>
{
    public override Job1Result Run()
    {
         //
    }
}

【讨论】:

  • 虽然我喜欢这个解决方案,但我很确定我不能使用它,因为 Entity Framework 不允许将泛型类用作实体。如果我错了,请纠正我。
  • @JensOlsen112:我以前从未使用过实体框架,但Job1 在技术上不是泛型类,它只是继承自一个。
  • 请注意,这种方法将为每个具体类型创建兄弟类,这通常不是人们期望/想要的继承:Job1 : Job&lt;Job1Result&gt;Job2 : Job&lt;Job2Result&gt; 彼此不相关,因为没有共同的父类.
【解决方案3】:

这是一个例子,希望对你有帮助。

public interface IEvent
{
    Type GetEventType();
}


public abstract class AEvent<A>: IEvent where A: struct
{
    public Type GetEventType()
    {
        return typeof (A); // return sub struct type
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2010-12-13
    • 2011-12-16
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多