我有四个类。Request、DerivedRequest、Handler和DerivedHandler。Handler类有一个属性,声明如下:
public abstract Request request { get; set; }
DerivedHandler需要重写此属性,以便返回DerivedRequest:
public override DerivedRequest request { get; set; }
有人对如何使这个工作有什么想法吗?
我有四个类。Request、DerivedRequest、Handler和DerivedHandler。Handler类有一个属性,声明如下:
public abstract Request request { get; set; }
DerivedHandler需要重写此属性,以便返回DerivedRequest:
public override DerivedRequest request { get; set; }
有人对如何使这个工作有什么想法吗?
这并不是一个好的结构方式。可以采取以下方法之一:
1)只需不改变返回类型,在子类中正常重写即可。在DerivedHandler
中,您可以使用Request
的基类签名返回DerivedRequest
的实例。任何使用此代码的客户端都可以选择将其强制转换为DerivedRequest
。
2)如果它们不应该是多态的,请改用泛型。
public abstract class HandlerBase<T> where T: Request
{
public abstract T Request {get;set;}
}
public class Handler: HandlerBase<Request>()
public class DerivedHandler: HandlerBase<DerivedRequest>()
class HandlerBase<A,B,C,..> where A:classA, B:classB,...
的事情吗? - JavidanRequest
属性的返回类型转换为Handler
类的泛型类型参数来解决这个问题。然后,DerivedHandler
类会指定DerivedRequest
类作为该类型参数的参数。// Handler.cs
public class Handler<TRequest> where TRequest : Request
{
public TRequest Request { get; set; }
}
// DerivedHandler.cs
public class DerivedHandler : Handler<DerivedRequest>
{
}
除了隐藏原始属性外:
public new DerivedRequest Request { get;set;}
public DerivedRequest DerivedRequest {/* make adequate conversions here*/ }
编辑:
您无法更改派生类型的类型,但是new
可能会有所帮助:
在派生类型中...
public new DerivedRequest request
{
get{return (DerivedRequest) base.request;}
set{base.request = value;}
}
public override Request request
{
get{return base.request;}
set{base.request = (DerivedRequest) value;} // Throws InvalidCastException if misused.
}
public class Request{}
public class DerivedRequest : Request{}
public class Handler<T>
where T : Request
{
public abstract T Request { get; set; }
}
public class DerivedHandler : Handler<DerivedRequest>
{
public override DerivedRequest Request { get; set; }
}
这在理论上是不可能的。覆盖必须对返回类型协变(即,返回类型必须更具体或相同),并且对于参数来说是逆变的(即,参数类型必须更少具体或相同)。因此,您的新类型必须在Request
方面同时具有协变和逆变性--这意味着,唯一可能的类型就是Request
。
出于这个原因,在C#中不允许更改覆盖属性的类型。