使用派生类覆盖基类的属性

Vah*_*hid 4 c# polymorphism inheritance properties

在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; }
   }
Run Code Online (Sandbox Code Playgroud)

更新:

当前的实施有什么问题?

在基地:

public virtual ReinforcementShape Shape { get; set; }
Run Code Online (Sandbox Code Playgroud)

在派生中:

public new RebarShape Shape { get; set; }
Run Code Online (Sandbox Code Playgroud)

Him*_*ere 6

您可以使用泛型执行此操作,无需覆盖基类成员:

public class Reinforcement<T> where T: ReinforcementShape 
{
    public <T> Shape { get; set; }
}

public class Rebar : Reinforement<RebarShape>
{
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以轻松地创建ReBar并访问其Shape-property的实例,该实例是以下实例RebarShape:

var r = new Rebar();
r.Shape = new RebarShape();
Run Code Online (Sandbox Code Playgroud)

ReinforcementShape尝试为该属性分配实例将导致编译时错误,此时只有a RebarShape有效.

编辑:根据您的编辑.您只能通过覆盖它的实现来覆盖成员,而不是它的返回值.所以virtual在你的情况下使用不会做任何事情.但是,正如R.Rusev已经提到的那样,你只需要在new派生成员上使用-keyword,它实际上会提供一个全新的成员,它与你的基类中的成员同名.但实际上它是一个完全不同的成员,它与前者没有任何共同点.但是,当您编写以下内容时

Reinforcement r = new Rebar();
// assign value to Shape
var shape = r.Shape;
Run Code Online (Sandbox Code Playgroud)

使用原始实现,而不是你的新实现.所以shape是类型ReinforcementShape而不是RebarShape.解决这个问题的唯一方法是声明r作为Rebar摆在首位:

Rebar r = new Rebar();
// assign value to Shape
var shape = r.Shape;
Run Code Online (Sandbox Code Playgroud)

但这对你的应用程序的任何用户来说都很混乱,也许对你自己也是如此.我根本不建议使用该关键字.更好地使用第一种方法.