簡體   English   中英

帶有公共 getter 的抽象屬性,可以在具體類中定義私有 setter 嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM