C# 如何为从抽象实现的方法强制执行派生类型?

C# 如何为从抽象实现的方法强制执行派生类型?,c#,C#,我的抽象类有一个抽象的方法,如下所示: public abstract void Run(BaseType baseType); 现在在我必须实现这个函数的派生类中,我希望它只接受来自BaseType 因此,它将: public override void Run(DerivedType derivedType){} 有什么办法可以强制执行吗 目前我必须做: public override void Run(BaseType baseType) { if(!(baseType is

我的抽象类有一个抽象的方法,如下所示:

 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
   }
}

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

您希望该语言做一些它确实不应该做的事情。您需要一个协变参数,它违反了Liskov替换原则:它使抽象类的实现在抽象基类可用的所有情况下都不可用。这就是抽象基类的全部出发点。

虽然使用协变返回类型(返回比抽象方法指定的更派生的类型)是有意义的,但该语言也阻止您这样做。

您希望该语言做一些它确实不应该做的事情。您需要一个协变参数,它违反了Liskov替换原则:它使抽象类的实现在抽象基类可用的所有情况下都不可用。这就是抽象基类的全部出发点。

虽然使用协变返回类型(返回比抽象方法指定的更派生的类型)是有意义的,但该语言也阻止您这样做。

我有时使用这种模式:

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();
    }
}
公共接口IHandler
{
无效运行();
}
公共抽象类BaseHandler:IHandler
其中TObj:BaseType
{
受保护的只读TObj_obj{get;set;}
公共BaseHandler(TObj obj)
{
这个._obj=obj;
}
公开摘要无效运行();
}
公共类DerivedHandler:BaseHandler
{
公共DerivedHandler(DerivedType obj):基本(obj)
{
}
公共覆盖无效运行()
{
//用底座做东西
}
}
公共类搬运服务
{
公共IHandler CreateHandler(TObj obj)
{
//根据DI容器的不同,您可以从容器中自动解决此问题
if(typeof(TObj)=typeof(DerivedType))
{
返回新的DerivedHandler(obj);
}
抛出新的NotImplementedException();
}
}
这允许您为每个派生类型定义一个特定的“处理程序”,然后通过公共接口访问它

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


等我有时间时,我会再填写一些信息。

我有时会使用这种模式:

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();
    }
}
公共接口IHandler
{
无效运行();
}
公共抽象类BaseHandler:IHandler
其中TObj:BaseType
{
受保护的只读TObj_obj{get;set;}
公共BaseHandler(TObj obj)
{
这个._obj=obj;
}
公开摘要无效运行();
}
公共类DerivedHandler:BaseHandler
{
公共DerivedHandler(DerivedType obj):基本(obj)
{
}
公共覆盖无效运行()
{
//用底座做东西
}
}
公共类搬运服务
{
公共IHandler CreateHandler(TObj obj)
{
//根据DI容器的不同,您可以从容器中自动解决此问题
if(typeof(TObj)=typeof(DerivedType))
{
返回新的DerivedHandler(obj);
}
抛出新的NotImplementedException();
}
}
这允许您为每个派生类型定义一个特定的“处理程序”,然后通过公共接口访问它

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


等我有时间的时候,我会再补充一些信息。

我想在设计时你不能强制执行它。在使用实际实例运行时,您只需检查一次类型,并记住。
public new void Run(DerivedType DerivedType){base.Run(DerivedType);}
如果我了解您想要什么?@vasily.sib
base.Run
将无法工作,因为基本方法是抽象的-没有主体。但我可以试试。这算是实现抽象方法吗?否则,它仍然不是每一个可强制执行的。@WDUK直截了当地说,在重新设计应用程序的这一部分时,您可能会获得更大的成功。我认为在设计时,您无法强制执行它。在使用实际实例运行时,您只需检查一次类型,并记住。
public new void Run(DerivedType DerivedType){base.Run(DerivedType);}
如果我了解您想要什么?@vasily.sib
base.Run
将无法工作,因为基本方法是抽象的-没有主体。但我可以试试。这算是实现抽象方法吗?否则,它仍然不是每一个都可以执行的。@WDUK直截了当地说,您可能会更成功地重新设计应用程序的这一部分。那么,它的干净设置是什么呢?我需要在哪里实现方法以确保其存在,但首先还需要类型检查?当做了很多这样的事情时,忘记类型检查在大型软件中可能会有问题,而且很容易忘记。@WDUK您试图解决的问题是什么?既然您遇到了这个问题,我觉得可能有更好的方法来解决您的业务问题,完全避免这个编程问题。我希望我的所有派生类都有run方法(因此我使用abstract来保证它),但是,由于这些派生类链接到不同的系统,这些系统的初始化方法具有不同的参数,因此,
override Run
方法需要根据它们链接到的系统接受不同的派生类型