2017-02-16 115 views
2

在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; } 
+1

您无法重写某个属性并将其更改为返回类型。 –

回答

4

你可以使用泛型做到这一点,不需要重写基类成员:

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实例分配给该属性将导致组合物1 le-time错误,此时只有一个RebarShape有效。

编辑:根据您的编辑。你只能通过覆盖它的实现来覆盖成员,而不是它的返回值。所以使用virtual不会为你的情况做任何事情。然而,正如R.Rusev已经提到的,你只需要你的派生成员上的new关键字,它实际上会提供一个全新的成员,其名称与你的基类中的名称相同。但实际上它是一个完全不同的成员,与前者完全不同。但是,当你写下面的内容

Reinforcement r = new Rebar(); 
// assign value to Shape 
var shape = r.Shape; 

最初的实现是使用,而不是你的neew之一。所以shape将是ReinforcementShape而不是RebarShape。解决这个问题的唯一方法是首先声明rRebar

Rebar r = new Rebar(); 
// assign value to Shape 
var shape = r.Shape; 

但是,这是相当混乱到您的应用程序的任何用户,也许自己还。我一般不建议使用该关键字。更好地使用第一种方法。

+0

你能看到我的更新吗? – Vahid

+0

不幸的是我不能使用泛型。因为我需要为这些类的几个属性执行此操作。 – Vahid

+0

@Vahid:那么你应该添加其他属性到你的问题。一般来说,泛型是更好的方法(与'new'关键字答案相比) – phifi

1

可以使用new关键字做到这一点。所以你对Rebar类的定义将如下所示。

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

'新'关键字不会*覆盖*,但*隐藏*基类的实现。无论如何,即使使用关键字,当你使用派生类的实例作为基类的变量时,原来的成员被使用,而不是新的。 – HimBromBeere

+0

谢谢。你能否也请让我看看基类中的实现。我也希望能够在基类中设置。 – Vahid

+0

@Vahid基类保持不变。 –