Override Get, But Not Set
我有一个抽象类,它定义了一个
1 2 3 4 5 | public abstract BaseClass { public abstract double MyPop {get;} } |
但是,在一些派生类中,我需要一个
1 2 3 4 5 | public class DClass: BaseClass { public override double MyPop {get;set;} } |
号
问题是,我有一个编译错误,说
*.set: cannot override because *. does not have an overridable set accessor.
号
尽管我认为上述语法是完全合法的。
对此有什么想法吗?解决方法,或者为什么是这样?
编辑:我能想到的唯一方法是把
一个可能的答案是重写getter,然后实现一个单独的setter方法。如果不希望在基中定义属性setter,则没有其他许多选项。
1 2 3 4 5 6 7 8 9 | public override double MyPop { get { return _myPop; } } public void SetMyPop(double value) { _myPop = value; } |
号
做你想做的事是不可能的。必须在抽象属性中定义setter,否则将无法正确重写它。
唯一我知道在哪里定义getter和实现getter/setter的情况是使用接口:
1 2 3 4 5 6 7 8 9 | public interface IBaseInterface { double MyPop { get; } } public class DClass : IBaseInterface { public double MyPop { get; set; } } |
C 6.0中的新功能:
如果只在构造函数中调用setter,则可以使用只读属性解决此问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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;} } |
如果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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
你确定如果你找到一种方法去做你想做的事情会是一个好的设计吗?
它将允许子类的对象进行父类对象无法进行的状态更改。这不会违反里斯科夫替代原则吗?
这是不可能的原因,因为参数是通过c_"魔术师化"而存在的。定义参数时,C创建隐式getter和setter操作的私有字段。如果基类中没有setter,则无法从子类中写入的方法更改此变量(因为私有标志甚至禁止子类访问它)。通常情况下,它使用基类的隐式setter。
如果不是所有的子类都能做到,我不建议将集合放在基类中,因为这违背了多态编程的整个原则(抽象类中定义的任何抽象方法都必须由子类实现)。如其他答案所述,创建一个特殊的setter方法可能是最好的方法。
你可以这样做:
埃多克斯1〔2〕
使用testderived将具有您要查找的功能。从这个方法中我能看到的唯一缺点是,您必须在TestDerivedHelper中实现每个抽象方法,但它稍后会提供更多的控制。
希望这有帮助。;)
即使这条线是旧的,我也在提出我的解决方案,以防它能帮助别人。它不是我自己的,而是基于其他主题的答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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; } } } |
。
此解决方案为需要修改访问器的每个此类属性添加一行额外的代码。但是,外部可见性没有变化,并且提供了所需的功能。
围攻
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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); } } } |
。
Using TestDerived will have the functionality you're looking for. The
only drawback I can see from this method is that you have to implement
every abstract method in TestDerivedHelper, but it gives you more
control later.
号
我使用这种方法,并为我很好地工作。此外,我还将"testderivedHelper"类抽象为抽象类,然后必须在"testderived"类上实现所有方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 } |
。
如果需要从
编辑:
好吧,我可能对这个回答很仓促,但我现在已经多考虑了。
必须使用抽象基类吗?如果不需要,请尝试以下操作:
1 2 3 4 5 6 7 8 9 | public interface ISomeRelevantName { double MyPop { get; } } public class DClass : ISomeRelevantName { public double MyPop { get; set; } } |
不能重写set访问器,因为基类没有定义set访问器。
您可以使用
为什么不在具有私有setter的基类中拥有一个属性,然后在需要setter的子类中重写它并将其公开呢?