【问题标题】:CA1500 vs. SA1309 - Which one wins?CA1500 vs. SA1309 - 谁赢了?
【发布时间】:2011-03-14 00:35:22
【问题描述】:

我先声明一下,我知道代码分析和 StyleCop 都是作为指导方针的,而且许多人还是选择忽略这些。不过话虽如此,我想看看关于这两条规则的普遍共识是什么。

Rule CA1500 表示不要让参数名称和私有字段名称相同。

另一方面,Rule SA1309 表示不要为成员添加下划线或“m_”前缀。

这使我们几乎没有选择将私有支持字段与其相应参数区分开来。举这些例子。

SA1309 抱怨:

class SomeClass
{
    int _someField;

    public SomeClass(int someField)
    {
        this._someField = someField;
    }
}

CA1500 抱怨:

class SomeClass
{
    int someField;

    public SomeClass(int someField)
    {
        this.someField = someField;
    }
}

我有什么选择?我不想创建私有支持字段 PascalCase,因为这是(我相信相当普遍的)公共字段/属性的约定。而且我不想重命名其中一个,只是为了解决歧义。

所以我只剩下上述两个中的一个,这需要我取消 SA/CA 规则之一。

你们通常做什么?更重要的是,这些规则的作者认为您应该怎么做(因为在他们的文档中都没有提供替代解决方案)?

【问题讨论】:

  • 你的第一个例子不能编译,名字搞砸了:)
  • 我通常违反 CA1500。但我只有 Pro,没有 TFS,所以我从来没有看到警告。 :)
  • 我一直违反 CA1500,但到目前为止从未收到警告,尽管它启用了 CA1500。这条规则有什么神奇之处吗?
  • @Albic - 同样在这里,似乎我们刚刚开始收到警告。我们总是走第二个例子的路。我们最近确实从 FxCop 1.36 转到了 VS2010 中的代码分析,但我不认为这是一个新规则。我不确定。

标签: c# naming-conventions code-analysis fxcop stylecop


【解决方案1】:

简单,当有类时,使用后缀“字段”作为私有字段:

 private Int32 counterField;

 public Int32 Counter
 {
     get
     {
          return this.counterField;
     }

     set
     {
           if (this.counterField != value)
           {
                this.counterField = value;
                this.OnPropertyChanged("Counter");
            }
      }

你可以同时满足这两个规则。用任何字符或匈牙利语前缀装饰你的变量是部落的。每个人都可以在 StyleCop 或 FXCop 中找到他们不喜欢的规则,但一个标准只有在每个人都使用它时才有效。自动清理代码的好处远远超过您个人对语言的“艺术”贡献。

【讨论】:

    【解决方案2】:

    没有冲突。更改参数名称。

    public class SomeClass
    {
        private int namedField { get; set; }
    
        public SomeClass(int differentlyNamedField)
        {
            this.namedField = differentlyNamedField;
        }
    }
    

    【讨论】:

    • 不知道为什么投反对票。问题中的两条规则根本不冲突。任何其他回复都将“主要基于意见” - 由于这一事实,这将要求关闭问题。
    【解决方案3】:

    我能想到的唯一替代方案似乎可以满足这两个规则,并且我实际上已经看到在任何地方使用类似于以下内容。我自己不遵循这个约定,因为它看起来很笨拙。

    public class Class1
    {
        // prefix private fields with "m"
        private int mValue1;
    
        public int Value1
        {
            get { return mValue1; }
            set { mValue1 = value; }
        }
    
        private string mValue2;
    
        public string Value2
        {
            get { return mValue2; }
            set { mValue2 = value; }
        }
    
        // prefix parameters with "p"
        public bool PerformAction(int pValue1, string pValue2)
        {
            if (pValue1 > mValue1)
            {
                mValue2 = pValue2;
                return true;
            }
            else
            {
                return (mValue2 == pValue2);
            }
        }
    }
    

    【讨论】:

    • 这将破坏 SA1305 “FieldNamesMustNotUseHungarianNotation”。这个link 展示了如何修改 StyleCop 以允许某些前缀。内容也在 StyleCop 帮助中。
    • 同上。使用“m”就像使用“_”一样具有部落特色。不要再试图定义自己的语言了。
    【解决方案4】:

    我们关闭 SA1309。其背后的推理相当薄弱。

    我们的团队认为,私人成员以下划线开头的广为接受的做法远远超过了有人可能对代码使用不同的编辑器的想法,无论如何,这在我们的商店中从未发生过。至于提供“立即区分”,下划线也可以做到这一点。

    如果您确实有开发人员仍然使用“m_”并且您仍然需要检查它,您可以为此编写一个快速规则。

    【讨论】:

    • 谢谢,这似乎是最合乎逻辑的方法。
    【解决方案5】:

    这是我通常的解决方案:

    class SomeClass
    {
        int SomeField{get;set;}
    
        public SomeClass(int someField)
        {
            SomeField = someField;
        }
    }
    

    【讨论】:

    • 我也尽可能使用自动实现的属性(大多数情况下),但在某些情况下,我有私有字段而不将它们公开为公共属性。
    【解决方案6】:

    根据我从 Microsoft 看到的情况,我说 CA1500 胜出。

    如果您查看 BCL,大多数代码都会在本地字段前加上下划线。

    【讨论】:

    • 那是旧代码吗?在编写 BCL 的同时发明了约定
    • 我已经阅读了 BCL 中的代码,我会责备程序员的编写... :) 只是说,仅仅因为微软内部有人这样做并不意味着它是正确的——甚至是推荐的微软作为一个整体。
    • @Stephen Cleary - 这也是我的想法。我看到那里出现了非常不一致的做法,并尽量不要将他们的代码用作最佳实践的圣杯。
    • StyleCop 在某种程度上胜过 BCL 或“框架设计指南”风格。基本上 BCL 代码和书是由 C++ 开发人员编写的,他们在 BCL 中保持风格一致。 StyleCop 用于 C#。多年来,C# 开发了自己的风格,StyleCop 反映了这一点。 blogs.msdn.com/b/sourceanalysis/archive/2008/05/25/…
    猜你喜欢
    • 2013-02-23
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    相关资源
    最近更新 更多