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