3

假设我有class Foo并且

class FooFrobber
{
   private Foo _foo;

   FooFrobber(Foo foo)
   {
       _foo = foo;
   }

   Frob()
   {
      _foo.FrobCount += 1;
   }
}

这似乎_foo是一个private字段的好名称,但如果我想将其设为internalorprotected变量怎么办?约定(http://weblogs.asp.net/lhunt/archive/2004/08/17/CSharpCodingStandardsv113.aspx via Style guide for c#?)似乎是使用没有 m_ 或尾随 _ 的 StudlyCaps,这意味着我会宣布protected Foo Foo。这似乎可行,但隐藏类名似乎有点奇怪。样式指南说所有字段都应该是私有的,但这似乎有点过分(但也许这是我内心的 python 说话)。无论如何,如果我们想将 _foo 包装在一个属性中,您似乎也会遇到同样的问题。

我是否应该总是为该字段取一个不同的名称,例如在 MyFoo 中?可以保持原样吗,因为编译器似乎不介意?

4

3 回答 3

2

允许和常见的做法是具有与其类型共享相同名称的字段/属性。从 FCL 中想到的第一个例子是DispatcherObject.Dispatcher,它返回一个 type 的实例Dispatcher

但是,我个人更喜欢避免将字段声明为受保护,而是使用属性。如果您想避免与声明支持字段相关的编码,您可以使用自动实现的属性:

protected Foo Foo { get; set; }

使用属性的优点是您可以为 getter 和 setter 应用不同的访问修饰符:

protected Foo Foo { get; private set; }

编辑:使用受保护属性而不是受保护字段的优点是它们允许您更改它们的实现——例如,引入值验证或更改通知——而不会破坏可能访问它的外部库。

例如,假设您想扩展您的类以实现INotifyPropertyChanged. 如果您使用的是受保护的字段,则没有直接的方法可以检测该字段的值何时被消费程序集更改(除非您也更改了外部程序集的实现)。如果您使用的是受保护的属性,则可以简单地更改其实现,而无需对使用程序集进行任何更改:

private Foo foo;

protected Foo Foo 
{ 
    get
    {
        return foo;
    }
    set
    {
        if (foo != value)
        {
            foo = value;
            OnPropertyChanged("Foo");
        }
    }
}

编辑2 : LBushkin 的回答中给出了在字段上使用属性的更多优点。

将字段更改为属性似乎会破坏 ABI。我还没有在权威来源中找到它(我没有花太多时间寻找);但是,根据pst 的评论

可以更改属性背后的代码(使用自定义私有支持字段或其他)。但是,将公共成员变量更改为属性是 ABI(应用程序二进制接口)中的一项重大更改。

根据jstedfast 的回答

首先要记住的是属性访问器被编译成方法。这意味着它具有与仅读取/写入类成员变量不同的 ABI,即使它在语法上可能看起来相同。

于 2012-06-05T18:39:07.093 回答
1

这是一种常见的做法,主要来自C++世界,将字段命名_为前面。像这样的命名转换是绝对可以的,直到它们符合开发组的要求。

在理想世界中,或者(比如说)尽可能多地命名变量的方向,是不要在其名称中突出显示type变量的名称,而是它在这个程序中所代表的含义。

所以而不是拥有(说)

string sName, 有一个string userName, 而不是Robot robot, 有Robot conveyor, 等等...

希望这可以帮助。

于 2012-06-05T18:45:18.107 回答
0

我认为保持原样是绝对可以的。编译器能够判断您的代码是指类还是属性,以及如果类名足够表达,为什么还要引入另一个术语。

于 2012-06-05T18:38:39.570 回答