繁体   English   中英

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

[英]Override property of the base class with a derived class

在C#代码中,如果Rebar类派生自Reinforcement类,则RebarShape类继承了ReinforcementShape类。 是否可以使用RebarShape类覆盖基类中的属性ReinforcementShape

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

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

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

public class Rebar : Reinforement<RebarShape>
{
}

现在,您可以轻松创建ReBar实例并访问其Shape -property,它是RebarShape一个实例:

var r = new Rebar();
r.Shape = new RebarShape();

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

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

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;

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

您可以使用new关键字来执行此操作。 所以你对Rebar类的定义将如下所示。

public class Rebar : Reinforement
{
    public new RebarShape Shape
    {
        get { return (RebarShape)base.Shape; }
        set { base.Shape = value; }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM