相比于让继承者实现抽象的只读属性,拥有只读字段有什么优缺点呢?(这里以C#为例,但其实语言并不重要)
以下是两种实现方式:
readonly field; inheritors have to inject the value in the constructor
interface IFace { public int Field { get; } } abstract class Base : IFace { private readonly int field; protected Base(int field) { this.field = field; } public int Field { get { return this.field; } } } class Impl { public Impl() : base(1) { } }
abstract getter-only property; inheriters have to implement the property
interface IFace { public int Field { get; } } abstract class Base : IFace { // default constructor can be used public abstract int Field { get; } } class Impl { public override int Field { get { return 1; } } }
int Field
,其值不会改变。然而,我可以看到以下几点区别:
1.
field
的值绑定到每个实例,没有什么阻止子类在它们的构造函数中接收该值(public Impl(int field) : base(field)
)。每个单独实例都需要存储该字段的内存。这可能不是大问题,但一定要牢记。所传达的意图是:该值只能在构造函数中设置,不能在之后更改(忽略反射)。2.
Field
的(返回)值绑定到每个类型,但没有什么阻止子类在每次调用getter时生成/计算值,潜在地每次返回不同的值。public overried int Field { get { return DateTime.UtcNow.Second; } }
内存只在IL中需要,因为该值通常不存储在任何地方,在返回前始终计算(导致加载指令以及其他操作)。传达的意图应该是:该值绑定到类型(并且不应该在调用之间更改,但没有办法强制执行)。但实际上,传达的意图是:你需要提供此属性,我不关心你如何实现以及它返回哪个值。还有什么关键区别我遗漏了吗?是一个优于另一个,还是需要根据具体情况决定?
我猜我正在寻找一种将只读(常量)值绑定到类型的构造/模式/语言功能,但在实例级别公开该值。 我知道我可以在每个继承类型中使用静态字段,但没有办法从公共基类(或接口)强制执行此操作。此外,当仅具有对该类型实例的引用时,不能调用静态字段。 想法?我很高兴收到不同编程语言的答案。