如果你碰到一个这样的抽象类:
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; } }
这样就什么问题都没有了。