重复的私有成员变量是否优先于共享受保护成员?

时间:2015-07-06 21:15:03

标签: c# coding-style

这是我在最近一直在研究的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成员是否“被视为有害”?

2 个答案:

答案 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字段。