这是我在最近一直在研究的C#代码库中注意到的一个成语:
class Base
{
private readonly MemberClass _memberVariable;
public Base(MemberClass memberValue)
{
_memberVariable = memberValue;
}
// methods accessing memberVariable...
}
class Derived : Base
{
private readonly MemberClass _memberVariable;
public Derived(MemberClass memberValue) : base(memberValue)
{
_memberVariable = memberValue;
}
// methods accessing memberVariable...
}
基类及其派生类都有一个成员变量,它在各自的构造函数中初始化,但不是在基类中将成员声明为protected
并且在子类中使用它,每个子类都有它自己的private
成员副本。
我对此的第一反应是这是一次不必要的重复。在考虑它时,我觉得复制可能是合理的,因为它减少了基类和派生类之间的耦合量,并防止基类的更改导致其子类中的无意中断。
C#中的protected
成员是否“被视为有害”?
答案 0 :(得分:3)
我会认为受保护的字段有害 - 如果值应该始终相同,我也会认为数据重复是有害的。但是,基类可以通过属性公开私有字段的值:
class Base
{
private readonly MemberClass memberVariable;
protected MemberClass MemberProperty { get { return memberVariable; } }
public Base(MemberClass memberValue)
{
this.memberVariable = memberValue;
}
// methods accessing memberVariable or MemberProperty...
}
class Derived : Base
{
public Derived(MemberClass memberValue) : base(memberValue)
{
}
// methods accessing MemberProperty...
}
在C#6中,基类变得更简单:
class Base
{
protected MemberClass MemberProperty { get; }
public Base(MemberClass memberValue)
{
this.MemberProperty = memberValue;
}
// methods accessing MemberProperty...
}
这仍然是一个由私有只读字段支持的受保护属性 - 只是编译器为你做了所有的样板。
答案 1 :(得分:1)
受保护的成员是否被认为是有害的"在C#?
一般会员?不,当然。在C#代码中有protected
个成员有很多充分的理由。
此外,我认为显然您在示例中使用的代码已被破坏。始终拥有完全相同值的两个副本是浪费的,如果有的话,可能会产生错误(只要你有两个应该具有相同值的字段,你现在就有机会让这些值不是同样的,因此最终破坏了某些代码。
至于protected
字段的具体问题是什么?我会在这里对Jon的意见表示异议,至少在某种程度上是这样的:对于一个readonly
领域,恕我直言,在某些情况下它完全没问题。
将这样的字段封装在属性中的主要原因是,以后可以详细说明实现,而不必重新编译相关代码(假设代码在不同的程序集中)。
但恕我直言,这样的领域很可能从不需要详细说明其实施。这些字段通常用作恒定值的来源。一个比只返回一个字段值更精细的东西的getter虽然并不是很少见,但也不是那么平常(我能想到的最大的例外是懒惰初始值)。
目前,我们大多数人都在使用C#5或更早版本,而且现在可能已经有一段时间了。在广泛使用C#6语法之前,我要说在某些特定情况下使用 当然,代码越复杂,好的,安全的抽象就越有用,你就越有可能坚持使用真正封装的只读属性。 但作为一个绝对的规则?不,我认为有必要全面禁止readonly protected
字段是简明扼要而没有重大维护/正确性危害。< / p>
readonly protected
字段。