抽象属性与公共getter,定义私人setter在具体类可能吗?
我试图创build一个抽象类,定义一个属性与getter。 我想把它留给派生类来决定是否要为这个属性实现一个setter。 这可能吗?
我到目前为止:
public abstract class AbstractClass { public abstract string Value { get; } public void DoSomething() { Console.WriteLine(Value); } } public class ConcreteClass1 : AbstractClass { public override string Value { get; set; } } public class ConcreteClass2 : AbstractClass { private string _value; public override string Value { get { return _value; } } public string Value { set { _value = value; } } } public class ConcreteClass3 : AbstractClass { private string _value; public override string Value { get { return _value; } } public void set_Value(string value) { _value = value; } }
在ConcreteClass1
我得到了一个错误的set
。 它不能覆盖set_Value
因为AbstractClass中不存在可重写的set访问器。
在ConcreteClass2
我在两个Value
都得到一个错误,因为具有相同名字的成员已经被声明了。
ConcreteClass3
不会给出错误,但即使Value的set访问器将被编译为set_Value,它也不会以相反的方式工作。 定义一个set_Value
并不意味着Value
会得到一个set访问器。 所以我不能给一个ConcreteClass3.Value属性赋值。 我可以使用ConcreteClass3.set_Value(“value”),但这不是我想要在这里实现的。
是否有可能让抽象类需要一个公共的getter,而允许在派生类中定义一个可选的setter?
如果你想知道,这只是一个理论问题。 我没有真正的情况下需要这样的事情。 但我可以想象一个抽象类不关心一个属性如何设置,但是确实需要能够获取属性。
不幸的是,你不能做到你想要的。 你可以通过接口来做到这一点:
public interface IInterface { string MyProperty { get; } } public class Class : IInterface { public string MyProperty { get; set; } }
我会这样做的方法是在具体的类中有一个单独的SetProperty方法:
public abstract class AbstractClass { public abstract string Value { get; } } public class ConcreteClass : AbstractClass { private string m_Value; public override string Value { get { return m_Value; } } public void SetValue(string value) { m_Value = value; } }
find一个解决scheme: 如何在C#中用setter重写getter-only属性?
public abstract class A { public abstract int X { get; } } public class B : A { public override int X { get { return 0; } } } /*public class C : B //won't compile: can't override with setter { private int _x; public override int X { get { return _x; } set { _x = value; } } }*/ public abstract class C : B //abstract intermediate layer { public sealed override int X { get { return this.XGetter; } } protected abstract int XGetter { get; } } public class D : C //does same thing, but will compile { private int _x; protected sealed override int XGetter { get { return this.X; } } public new virtual int X { get { return this._x; } set { this._x = value; } } }
D
现在等同于从B
inheritance的类,同时也可以在setter中重载。
不是很优雅,但是如果没有像在具体的课程中做的那样,这是最接近你的
public class Concrete : AbstractClass { public new void DoSomething() { Console.WriteLine(Value); } } public abstract class AbstractClass { protected AbstractClass() { try { var value = Value; } catch (NotImplementedException) { throw new Exception("Value's getter must be overriden in base class"); } } public void DoSomething() { Console.WriteLine(Value); } /// <summary> /// Must be override in subclass /// </summary> public string Value { get { throw new NotImplementedException(); } } }