【问题标题】:Is it bad style to have a member with the same name as a class?有一个与类同名的成员是不好的风格吗?
【发布时间】:2012-06-05 18:34:47
【问题描述】:

假设我有class Foo

class FooFrobber
{
   private Foo _foo;

   FooFrobber(Foo foo)
   {
       _foo = foo;
   }

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

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

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

【问题讨论】:

标签: c# .net coding-style


【解决方案1】:

允许和常见的做法是让字段/属性与其类型共享相同的名称。从 FCL 中想到的第一个示例是 DispatcherObject.Dispatcher,它返回类型为 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");
        }
    }
}

编辑2LBushkin’s answer 中给出了使用属性优于字段的更多优点。

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

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

jstedfast’s answer:

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

【讨论】:

  • 许多 UI 对象中的另一个例子是属性 Color,它返回一个 Color。
  • 我想这是一个附带问题,但为什么在第一种情况下更喜欢属性而不是字段(没有访问修饰符更改?)是否有助于保留“ABI”以供以后版本更改?顺便说一句,感谢有关不同访问修饰符的提示!
  • 感谢您的更新。我想我应该更清楚地表达我的问题。假设我从一个字段开始,然后决定切换到一个属性——似乎我不会更改 API(现有代码将通过简单的重新编译来工作)。问题是我是否会破坏 ABI(即使没有重新编译,现有代码也能工作)。我猜(隐式)答案是肯定的,但运行时似乎应该能够在动态链接期间处理更改。
  • 感谢 Edit_2 -- 这回答了我的问题。
【解决方案2】:

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

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

所以不要(比如说)

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

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    我认为保持原样完全没问题。编译器能够判断你的代码是指类还是属性,如果类名足够表达,为什么还要引入另一个术语。

    【讨论】:

      猜你喜欢
      • 2020-07-17
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 2012-10-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多