【问题标题】:Overriding generic abstract method to return specific type覆盖通用抽象方法以返回特定类型
【发布时间】:2018-01-06 13:37:03
【问题描述】:

我有一个抽象类,它是下面的方法签名:

protected abstract TResponse Handle<TResponse>(T command)

在一个覆盖它的类中,我有如下内容:

protected override TResponse Handle<TResponse>(ListFilmsByIdCommand command)
{
    return 9;
}

但是,由于它无法将 int 转换为 TResponse,因此无法编译。如果我将TResponse 更改为int 或其他DTO 类型类,它也会失败。

有没有办法拥有抽象方法并覆盖它,以便我可以返回任何我想要的类型?

【问题讨论】:

  • 我不认为你可以用不同的返回类型覆盖它。您最好的选择似乎是返回对象类型而不是 TResponse。
  • 您的方法使用泛型,因此调用者可以定义返回的类型。如果调用者执行 var x = Handle(command) 那么返回一个 int 是有意义的。但是如果调用者做了 var x = Handle>(command) 呢?然后你应该返回一个字符串列表。

标签: c# generics


【解决方案1】:

您不能使用返回除TResponse 之外的任何内容的实现来覆盖TResponse Handle&lt;TResponse&gt;,因为这是方法签名向其调用者承诺的类型。

您可以将类型约束添加到TResponse 以让您构造和初始化它,但这会排除内置类型(例如int)以TResponse 的身份参与:

interface IInitializable {
    void Initialize(object obj);
}
...
protected abstract TResponse Handle<TResponse>(T command) where TResponse : new, IInitializable;
...
protected override TResponse Handle<TResponse>(ListFilmsByIdCommand command) where TResponse : new, IInitializable {
    var res = new TResponse();
    res.Initialize(9);
    return res;
}

【讨论】:

    【解决方案2】:

    当你有一个泛型方法时,这意味着该方法可以与任何类型的对象一起工作,这显然不是这里的情况。你的方法只能返回一个int。所以删除方法签名中的泛型。

    相反,让您的抽象类通用:

    class YourAbstractClass<T> {
        protected abstract T Handle(ListFilmsByIdCommand command);
    }
    

    然后,具体的子类可以这样做:

    class ConcreteSubclass : YourAbstractClass<int> {
        protected abstract int Handle(ListFilmsByIdCommand command) {
            return 9;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 2014-08-25
      • 2016-01-26
      • 2010-11-22
      • 2012-03-01
      • 1970-01-01
      相关资源
      最近更新 更多