views:

88

answers:

4

I'll prefix by saying that I understand that both Code Analysis and StyleCop are meant as guidelines, and many people chose to ignore these anyway. But having said that, I'd like to see what the general consensus is with regard to these two rules.

Rule CA1500 says don't make parameter names and private field names the same.

Rule SA1309, on the other hand, says don't prefix members with underscore or "m_".

This leaves us with little options for distinguishing private backing fields from their corresponding parameters. Take these examples.

SA1309 complains:

class SomeClass
{
    int _someField;

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

CA1500 complains:

class SomeClass
{
    int someField;

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

What options do I have? I don't want to make the private backing field PascalCase, because this is the (I believe fairly universal) convention for public fields/properties. And I don't want to rename one or the other, just for the sake of resolving ambiguity.

So I'm left with one of the above two, which would require me to suppress one of the SA/CA rules.

What do you guys typically do? And more importantly, what do the authors of these rules think you should do (as neither provide alternative solutions in their documentation)?

+1  A: 

Based on what I've seen from Microsoft themselves, I say CA1500 wins.

If you look at the BCL, most of the code prefixes local fields with an underscore.

Justin Niessner
But is that old code? Conventions were being *invented* while the BCL was written.
Stephen Cleary
@Stephen Cleary - I've seen it in code as new as 3.5.
Justin Niessner
@Justin: and I've read code in the BCL that I would chastise programmers for writing... :) Just sayin', just because someone inside Microsoft does it doesn't mean it's right - or even recommended by Microsoft as a whole.
Stephen Cleary
@Stephen Cleary - That's been my thinking as well. I see very inconsistent practices come out of there, and try not to use their code as the holy grail of best practices.
Jerad Rose
+1  A: 

Here is my usual solution:

class SomeClass
{
    int SomeField{get;set;}

    public SomeClass(int someField)
    {
        SomeField = someField;
    }
}
BioBuckyBall
I also use auto-implemented properties when possible (which is most of the time), but there are cases where I have private fields without exposing them as public properties.
Jerad Rose
For the cases where you can't use an auto-implemented property, maybe a more descriptive member variable would be useful, thus avoiding the CA clash with the parameter name.
Dan
+3  A: 

We turn off SA1309. The reasoning behind it is fairly weak.

Our team feels that the well-accepted practice of private members starting with underscores far outweighs the idea that someone might use a different editor on the code, which never happens in our shop anyway. As to providing an "immediate differentiation", the underscore does that as well.

If you really have developers that still use "m_" though and you still need to check for that, you could write a quick rule for just that.

womp
Thanks, this seems to be the most logical approach.
Jerad Rose
A: 

The only alternative I can think of that seems like it would satisfy both rules and that I have actually seen used anywhere is something like the following. I don't follow this convention myself, as it seems clumsy.

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);
        }
    }
}
Dr. Wily's Apprentice