2011-10-09 103 views
18

只有在对象安装时将会知道变量,并且以后不应更改时,应该使用只读字段。只读字段作为子类构造函数的目标

但是不允许从子类的构造函数分配只读字段。 如果超类是抽象的,这甚至不起作用。

有没有人有一个很好的解释,为什么这不是一个好主意,或缺乏C#languange? PS:当然,通过在超类的受保护构造函数中赋值readonly字段,您当然可以达到相同的结果。

+1

此外,编译器错误不准确:'错误68只读字段不能被分配给(除了在构造函数或变量初始值设定项)' – nicodemus13

回答

12

我可以看到这样做的唯一原因是因为“这只是这样设计的”,因为按照spec

直接分配到只读字段只能出现为 声明的或部分同一个类中的实例构造函数或静态构造函数。

只被读取的一点是,它不能改变,如果派生类可以修改那么这将不再是真实的,并会破坏封装(通过修改另一个类的内部)。

+1

这是真的。但是抽象类还是不适合?也许是因为有多个子类的可能性。 – philipshield

+2

这可能是不合适的,也许我们永远不会知道设计决定的确切原因。 –

+0

我不明白为什么它不适合抽象类,因为它们可以有构造函数,因此只读字段可以工作。 – pauloya

10
public class Father 
{ 
    protected readonly Int32 field; 

    protected Father (Int32 field) 
    { 
     this.field = field; 
    } 
} 

public class Son : Father 
{ 
    public Son() : base(5) 
    { 

    } 
} 

你可以尝试这样的东西,而不是!

+0

哦,我没看见!它是一个编辑? – renatoargh

+0

是的,我提到,在我的问题:) 此外,alexm在10分钟前发布了完全相同的答案。 – philipshield

+2

这不是一个编辑,但不是那么简单!这是一个整洁的解决方案 – philipshield

0

我想主要的原因是所有.NET语言实现

还有一个额外的复杂性,总有一个简单的解决方法:

abstract class Super 
{ 
    protected readonly int Field; 

    protected Super(int field) 
    { 
      this.Field = field; 
    } 
} 


class Sub : Super { 
    public Sub():base(5) 
    { 
    } 

}

0

我想通过这个模型抽象/虚拟财产在C#中。

abstract class Super { 
    protected abstract int Field { get; } 
} 

class Sub : Super { 
    protected override int Field { get { return 5; } } 
} 

在我看来,这是一个更好的解决方案,而不是有一个构造函数,包括每一个只读字段作为参数。对于一个因为编译器能够内联这个问题,以及还因为构造的解决方案看起来像这样在派生类:

class Sub : Super { 
    public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor 
} 

也可能无法工作,如果你已经有一个构造函数单个int值。

0

我宁愿在超类中使用受保护的构造函数(正如alexm所提到的),使用xml注释。 这应该消除DonAndre在代码评论中所说的问题。