重写抽象类的 get 属性并添加 set 属性

      如果你碰到一个这样的抽象类:

public abstract class NamedObject
{
    public abstract string Name { get; }
}

      并且需要实现一个子类 MyNamedObject,他的 Name 属性是可以被外部设置的,一开始如果你这样写:

public class MyNamedObject : NamedObject
{
    public override string Name { get; set; }
}

      Oops,编译报错了:

'MyNamedObject.Name.set': cannot override because 'NamedObject.Name' does not have an overridable set accessor

      试试用 new 怎么样:

public class MyNamedObject : NamedObject
{
    public override string Name { get; }

    public new string Name { set; }
}

public class MyNamedObject : NamedObject
{
    public override string Name { get; new set; }
}

      可惜的是这两种写法都不行,语法上 new 不可以这样用。事实上,对于这种情况,因为c#语言的约束,是没有办法实现在子类里将 Name 属性变为可写的,虽然理论上属性是被编译成方法的,CLR是支持属性方法的重写和新增的,仅仅因为语法的限制。如果碰巧你不能修改基类的代码,那只能写出:

public class MyNamedObject : NamedObject
{
    public override string Name { get; }

    public void SetName(string value) { }
}

      看起来不是很爽,但还过得去。如果你非要使用属性来实现Name,也是可以的,只是要加一层继承关系:

public class MyBasicNamedObject : NamedObject
{
    public override string Name { get; }
}

public class MyNamedObject : NamedObject
{
    public new string Name { get; set; }
}

      当然如果你恰好能够修改基类的话,最好把他改成:

public abstract class NamedObject
{
    public string Name { get { return GetName(); } }

    protected abstract string GetName();
}

public class MyNamedObject : NamedObject
{
    public new string Name { get; set; }

    protected override string GetName()
    {
        return Name;
    }
}

      这样就什么问题都没有了。

posted @ 2010-10-27 13:17  Yufei Huang  阅读(521)  评论(0编辑  收藏  举报