覆盖获取,但未设置

我有一个抽象类定义了一个get ,但没有set ,因为就抽象类而言,它只需要一个get

 public abstract BaseClass { public abstract double MyPop {get;} } 

但是,在一些派生类中,我需要一个set属性,所以我正在看这个实现

 public class DClass: BaseClass { public override double MyPop {get;set;} } 

问题是,我收到一个汇编错误,说

* .set:不能重写,因为*。 没有可覆盖的set访问器。

即使我认为上面的语法是完全合法的。

任何想法呢? 解决方法,或为什么这样呢?

编辑:我能想到的唯一方法是将getset都放在抽象类中,如果set被调用,并让子类抛出一个NotImplementedException ,那就没有必要了。 这是我不喜欢的,以及一个特殊的setter方法 。

C#6.0新增function:

如果只在构造函数中调用setter,则可以使用只读属性来解决此问题。

 void Main() { BaseClass demo = new DClass(3.6); } public abstract class BaseClass { public abstract double MyPop{ get; } } public class DClass : BaseClass { public override double MyPop { get; } public DClass(double myPop) { MyPop = myPop;} } 

一个可能的答案是重写getter,然后实现一个单独的setter方法。 如果你不想在基地定义属性设置器,你没有其他的select。

 public override double MyPop { get { return _myPop; } } public void SetMyPop(double value) { _myPop = value; } 

做你想做的事是不可能的。 您必须在抽象属性中定义setter,否则您将无法正确覆盖它。

我知道唯一一个定义getter和getter / setter的地方是使用一个接口:

 public interface IBaseInterface { double MyPop { get; } } public class DClass : IBaseInterface { public double MyPop { get; set; } } 

如果BaseClass在你自己的代码库中,那么你可以这样做:

 abstract public class BaseClass { abstract public double MyPop { get; protected set; } } public class DClass : BaseClass { private double _myProp; public override double MyProp { get { return _myProp; } protected set { _myProp = value; } } } 

编辑:您可以然后去在DClass SetMyProp(double myProp)或类似的公共方法。 你的领域模型的类devise应该清楚或者说明为什么你不能直接在基类中设置属性,为什么你可以在派生类中设置属性。

如果你find了一个办法,你确定做你正在做的事情会是一个好的devise吗?

这将允许子类的对象进行父类的对象无法进行的状态更改。 那不会违反里斯科换人原则吗?

你可以做这样的事情:

abstract class TestBase { public abstract int Int { get; } }

 class TestDerivedHelper : TestBase { private int _Int; public override int Int { get { return _Int; } } protected void SetInt(int value) { this._Int = value; } } class TestDerived : TestDerivedHelper { public new int Int { get { return base.Int; } set { base.SetInt(value); } } } 

使用TestDerived将有你正在寻找的function。 我从这个方法中唯一的缺点就是你必须在TestDerivedHelper中实现每个抽象方法,但是稍后会给你更多的控制权。

希望这可以帮助。 ;)

这是不可能的原因是由于参数被C#“Magicked”存在的方式。 当你定义一个参数时,C#创build一个隐式的getter和setter操作的私有字段。 如果在基类中没有setter,那么就不可能从写在子类中的方法中改变这个variables(因为私有标志甚至禁止子类访问它)。 通常会发生的是它使用基类的隐式setter。

如果不是所有的子类都可以这样做的话,我不会build议把这个集合放在基类中,因为这违背了多态编程的全部原则(任何在抽象类中定义的抽象方法都必须由子类实现)。 如其他答案中所述创build一个特殊的setter方法可能是最好的方法。

围城

 abstract class TestBase { public abstract int Int { get; } } class TestDerivedHelper : TestBase { private int _Int; public override int Int { get { return _Int; } } protected void SetInt(int value) { this._Int = value; } } class TestDerived : TestDerivedHelper { public new int Int { get { return base.Int; } set { base.SetInt(value); } } } 

使用TestDerived将有你正在寻找的function。 我从这个方法中唯一的缺点就是你必须在TestDerivedHelper中实现每个抽象方法,但是稍后会给你更多的控制权。

我使用这种方法,对我来说效果很好。 此外,我也做了我的“TestDerivedHelper”类的抽象,然后所有的方法必须在“TestDerived”类上实现。

 public abstract class BaseClass { public abstract double MyPop { get; } } public class DClass: BaseClass { private double _myPop = 0; public override double MyPop { get { return _myPop; } } // some other methods here that use the _myPop field } 

如果你需要从DClass外部设置属性,那么也许最好把setter放到基类中。

即使这个线程是老,我正在定位我的解决scheme,以防万一有人帮助。 这不是我自己的,而是基于其他SO主题的答案。

 public abstract BaseClass { public double MyPoP { get { return GetMyPoP; } } protected abstract double GetMyPoP { get; } } public class DClass: BaseClass { public new double MyPoP { get; set; } protected override double GetMyPop { get { return MyPoP; } } } 

此解决scheme为需要访问者修改的每个此类属性添加一行额外的代码。 但是,外部可见性没有变化,并提供了所需的function。

为什么不在基类中拥有一个私有的setter属性,那么在你的需要setter的子类中,覆盖它并将其公开。

由于基类没有定义set访问器,所以不能覆盖set访问器。

你可以做的是使用new关键字隐藏基类的实现,但这可能不是你想要的。

编辑:

好的,我可能已经对此作出了匆匆的回应,但我现在已经给了它更多的想法。

你必须使用抽象基类吗? 如果不是必需的,试试这个:

 public interface ISomeRelevantName { double MyPop { get; } } public class DClass : ISomeRelevantName { public double MyPop { get; set; } }