【问题标题】:How to enforce a derived type for a method that is implemented from abstract?如何为从抽象实现的方法强制执行派生类型?
【发布时间】:2018-07-06 05:56:48
【问题描述】:

我的抽象类有一个像这样抽象的方法:

 public abstract void Run(BaseType baseType);

现在在我必须实现此功能的派生类中,我希望它只接受来自BaseType 的特定派生类型

原来如此:

public override void Run(DerivedType derivedType){}

有什么办法可以强制执行吗?

目前我必须做的:

public override void Run(BaseType baseType) {
   if(!(baseType is DerivedType)) {
       // throw exception
   }
}

强制类型不是很严格——我想知道是否有一种方法可以做到这一点而无需不断添加类型检查?

【问题讨论】:

  • 我认为在设计时你不能强制执行它。在运行时使用实际实例,您只需检查一次类型并记住这一点。
  • public new void Run(DerivedType derivedType) { base.Run(derivedType); } 如果我明白你想要什么?
  • @vasily.sib base.Run 不起作用,因为基本方法是抽象的 - 它没有主体。但我可以试试。那算作实现抽象方法吗?否则,它仍然不是所有可执行的。
  • @WDUK 直言不讳,您在重新构建应用程序的这一部分时可能会更成功。

标签: c#


【解决方案1】:

我有时会使用这种模式:

public interface IHandler
{
    void Run();
}

public abstract class BaseHandler<TObj> : IHandler
    where TObj: BaseType
{
    protected readonly TObj _obj {get;set;}

    public BaseHandler(TObj obj)
    {
        this._obj = obj;
    }

    public abstract void Run();
}

public class DerivedHandler : BaseHandler<DerivedType>
{
    public DerivedHandler(DerivedType obj) : base(obj)
    {
    }

    public override void Run()
    {
        // do stuff with base._obj
    }
}

public class HandlerService
{
    public IHandler CreateHandler<TObj>(TObj obj)
    {
        // Depending on your DI container, you could resolve this automatically from the container
        if (typeof(TObj) == typeof(DerivedType))
        {
            return new DerivedHandler(obj);
        }
        throw new NotImplementedException();
    }
}

这允许您为每个派生类型定义一个特定的“处理程序”,然后通过一个通用接口访问它。

这个想法是您为对象实例化一个特定的处理程序,然后像Run() 这样的方法对该对象进行操作。然后,您可以通过服务解析处理程序。

稍后我有空再补充一些信息。

【讨论】:

    【解决方案2】:

    您希望语言做一些它确实不应该做的事情。您需要一个协变参数,这违反了 Liskov 替换原则:它使抽象类的实现并非在抽象基类可用的所有情况下都可用。这就是抽象基类的全部意义所在。
    尽管拥有协变返回类型(返回比抽象方法指定的更多派生类型)可能是有意义的,但该语言也会阻止您这样做。

    【讨论】:

    • 那么什么是干净的设置呢?我需要在哪里实现方法以确保它在那里,但还需要首先进行类型检查?在进行大量此类操作时 - 在大型软件中忘记类型检查可能会出现问题并且很容易忘记。
    • @WDUK 您要解决的问题是什么?既然您遇到了这个问题,我觉得可能有更好的方法来解决您的业务问题,从而完全避免这个编程问题。
    • 我希望我的所有派生类都有 run 方法(所以我使用 abstract 来保证它),但是由于这些派生类链接到不同的系统,这些系统的初始化方法具有不同的参数,@ 987654321@ 方法需要接受不同的派生类型,具体取决于它们链接到的系统。
    猜你喜欢
    • 1970-01-01
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2021-11-24
    相关资源
    最近更新 更多