[英]Abstract property with public getter, define private setter in concrete class possible?
我正在嘗試創建一個使用 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;
}
}
找到了一個解決方案:如何在 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
繼承的類,同時還可以在 setter 中覆蓋。
您可以只使用protected
訪問修飾符。 由於繼承,您不能使用private
。 它看起來像這樣:
public abstract class A
{
public abstract int prop { get; protected set; }
}
public abstract class B : A
{
public override int prop { get; protected set; }
}
不是很優雅,但它是你可以得到的最接近的東西,而無需像在具體類 3 中那樣做
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(); } }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.