将抽象readonly属性覆盖为读/写属性

Coi*_*oin 24 c# properties abstract

我想只强制从基本抽象类在给定属性上实现C#getter.如果需要,派生类可以为该属性提供一个setter,以供公共使用静态绑定类型.

给出以下抽象类:

public abstract class Base
{
    public abstract int Property { get; }
}
Run Code Online (Sandbox Code Playgroud)

如果我想要一个也实现了setter的派生类,我可以天真地尝试:

public class Derived : Base
{
    public override int Property
    {
        get { return field; }
        set { field = value; } // Error : Nothing to override.
    } 

    private int field;
}
Run Code Online (Sandbox Code Playgroud)

但是后来我遇到语法错误,因为我试图覆盖不存在的setter.我尝试了其他方式,例如声明基本setter私有等等,我仍然偶然发现所有类型的错误阻止我这样做.必须有办法做到这一点,因为它不会破坏任何基类合同.

顺便说一句,它可以通过接口完成,但我真的需要默认实现.

我经常偶然发现这种情况,我想知道是否有一个隐藏的C#语法技巧,否则我将使用它并实现一个手动SetProperty()方法.

Mar*_*ell 15

你不能直接这样做,因为你不能newoverride同一类型的同一签名; 有两个选项 - 如果您控制基类,则添加第二个属性:

public abstract class Base
{
    public int Property { get { return PropertyImpl; } }
    protected abstract int PropertyImpl {get;}
}
public class Derived : Base
{
    public new int Property {get;set;}
    protected override int PropertyImpl
    {
        get { return Property; }
    }
}
Run Code Online (Sandbox Code Playgroud)

否则,您可以在类层次结构中引入额外的级别:

public abstract class Base
{
    public abstract int Property { get; }
}
public abstract class SecondBase : Base
{
    public sealed override int Property
    {
        get { return PropertyImpl; }
    }
    protected abstract int PropertyImpl { get; }
}
public class Derived : SecondBase
{
    public new int Property { get; set; }

    protected override int PropertyImpl
    {
        get { return Property; }
    }
}
Run Code Online (Sandbox Code Playgroud)


Jes*_*olm 5

这能满足您的需求吗?

public abstract class TheBase
{
    public int Value
    {
        get;
        protected set;
    }
}
public class TheDerived : TheBase
{
    public new int Value
    {
        get { return base.Value; }
        set { base.Value = value; }
    }
}
Run Code Online (Sandbox Code Playgroud)

virtual除去,但是基准值仍然为值的唯一存储设备。所以这应该显示'5'。编译器应该大惊小怪b.Value = 4;

TheDerived d = new TheDerived();
d.Value = 5;
TheBase b = d;
//b.Value = 4;    // uncomment for compiler error
cout << "b.Value == " << b.Value << endl;
Run Code Online (Sandbox Code Playgroud)

-杰西