在C#代码中,如果Rebar
类派生自Reinforcement
类,RebarShape
类继承ReinforcementShape
类。是否可以使用ReinforcementShape
类覆盖基类中的属性RebarShape
?
public class ReinforcementShape
{
}
public class RebarShape : ReinforcementShape
{
}
public class Reinforcement
{
public ReinforcementShape Shape { get; set; }
}
public class Rebar : Reinforement
{
// I want to override the Shape property
// but with its derived class which is RebarShape
// override the base property somehow!
public RebarShape Shape { get; set; }
}
更新
目前的实施有什么问题?
在基地:
public virtual ReinforcementShape Shape { get; set; }
在派生中:
public new RebarShape Shape { get; set; }
答案 0 :(得分:5)
您可以使用泛型执行此操作,无需覆盖基类成员:
public class Reinforcement<T> where T: ReinforcementShape
{
public <T> Shape { get; set; }
}
public class Rebar : Reinforement<RebarShape>
{
}
现在,您可以轻松创建ReBar
的实例并访问其Shape
- 属性,该属性是RebarShape
的实例:
var r = new Rebar();
r.Shape = new RebarShape();
尝试将ReinforcementShape
的实例分配给该属性会导致编译时错误,此时只有RebarShape
有效。
编辑:根据你的编辑。您只能通过覆盖它的实现来覆盖成员,而不是它的返回值。所以使用virtual
不会在你的情况下做任何事情。但是,正如R.Rusev已经提到的那样,您只需要派生成员上的new
- 关键字,它实际上将提供一个全新的成员,该成员与您的基类具有相同的名称。但实际上它是一个完全不同的成员,它与前者没有任何共同点。但是,当您编写以下内容时
Reinforcement r = new Rebar();
// assign value to Shape
var shape = r.Shape;
使用原始实现,而不是您的新实现。因此shape
的类型为ReinforcementShape
,而不是RebarShape
。解决此问题的唯一方法是首先将r
声明为Rebar
:
Rebar r = new Rebar();
// assign value to Shape
var shape = r.Shape;
但这对你的应用程序的任何用户来说都很混乱,也许对你自己也是如此。我根本不建议使用该关键字。更好地使用第一种方法。
答案 1 :(得分:1)
您可以使用new
关键字来执行此操作。所以你对Rebar类的定义将是这样的。
public class Rebar : Reinforement
{
public new RebarShape Shape
{
get { return (RebarShape)base.Shape; }
set { base.Shape = value; }
}
}