覆盖获取,但未设置
我有一个抽象类定义了一个get
,但没有set
,因为就抽象类而言,它只需要一个get
。
public abstract BaseClass { public abstract double MyPop {get;} }
但是,在一些派生类中,我需要一个set
属性,所以我正在看这个实现
public class DClass: BaseClass { public override double MyPop {get;set;} }
问题是,我收到一个汇编错误,说
* .set:不能重写,因为*。 没有可覆盖的set访问器。
即使我认为上面的语法是完全合法的。
任何想法呢? 解决方法,或为什么这样呢?
编辑:我能想到的唯一方法是将get
和set
都放在抽象类中,如果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; } }