tags:

views:

244

answers:

9

I often find I want to write code something like this in C#, but I am uncomfortable with the identifier names:

public class Car
{
    private Engine engine;
    public Engine Engine
    {
        get
        {
            return engine;
        }
        set
        {
            engine = value;
        }
    }
    public Car(Engine engine)
    {
        this.engine = engine;
    }
}

Here we have four different things called "engine":

  • Engine the class. Engine seems like a good, natural name.
  • Engine the public property. Seems silly to call it MyEngine or TheCarsEngine.
  • engine the private field backing the property. Some naming schemes will recommend m_engine or _engine, but others say that all prefixes should be avoided.
  • engine the parameter name on the constructor. I've seen naming schemes that recommend prefixing an underscore on all parameters, e.g., _engine. I really dislike this, since the parameter is visible to callers via Intellisense.

The particular things I don't like about the code as written are that:

  • If you change the parameter name in the constructor but miss a use of it in the constructor body, you get a subtle bug that the compiler probably won't be able to spot.
  • Intellisense has a bad habit of autocompleting the wrong thing for you, and sometimes you won't notice it's changed the case. You will again get a subtle bug if the constructor body accidentally ends up this.engine = Engine;

It seems that each name is appropriate in isolation, but together they are bad. Something has to yield, but what? I prefer to change the private field, since it's not visible to users, so I'll usually end up with m_engine, which solves some problems, but introduces a prefix and doesn't stop Intellisense from changing engine to Engine.

How would you rename these four items? Why?

(Note: I realise the property in this example could be an automatic property. I just didn't want to make the example overcomplicated.)

See also: http://stackoverflow.com/questions/461231/am-i-immoral-for-using-a-variable-name-that-differs-from-its-type-only-by-case

+12  A: 

In this case, I would name them exactly as they are in the example.

This is because the naming is clear as to what data each element holds and/or will be used for.

The only thing I would change for C#3 is to use an auto-property which would remove the local variable.

Garry Shutler
Wow, this is a popular choice! I often did this and then felt wracked with guilt. I guess people don't find the problems I described with it to be bad in practice?
Weeble
For me it's all about cutting down on noise. Yes, there are chances of typos but: 1. you should have tests to catch the effects of typos, 2. you'll read the code at least 10 times more frequently than you'll modify it so any reading benefit far outweighs modification problems.
Garry Shutler
+1  A: 
  • Member: m_engine;
  • Static member: sm_engine;
  • Parameter: engine
  • Local variable: _engine
  • Class: Engine
  • Property: Engine

This makes it possible to name parameters and local variables differently.

Serhat Özgel
That may look dodgy but AFAIK that's what actually used inside the .NET Framework classes (I don't have Reflector at hand to check it though)
DrJokepu
It's a mixed bag in the fw source, sometimes 'm_' for private members, other times just '_'. Makes me ill when I see 'm_', it's so 90's. :)
Kev
A: 

I prefer to use some prefix (I use '_') for private fields, otherwise they look just the same as parameters and locals. Other than that, I use a similar approach to naming as you do here, though Engine might be a little to generic, depending on how general the program is.

I think I prefer CarEngine, or AutoEngine, or something like that, since programmers are fond of using Engine as a metaphor for things that don't correspond to real-life engines at all.

Barry Kelly
A: 

I normally prefix private fields with underscore, so I would call it _engine. And I often use very short (e.g. initial letter) parameter names, so that would be Engine e (after all, the intellisense users get the type and name). I either leave the class and object names the same or (more usually) come up with a different name, even if it's MyEngine or carEngine.

So:
public class Car

{    
    #region fields

    private Engine _engine;

    #endregion

    #region public properties

    public Engine carEngine { get { return _engine; } set { _engine = value; } }  

    #endregion 

    #region constructors 

    public Car(Engine e)    
    { 
        _engine = e; 
    }

    #endregion
}
gkrogers
Repeating the parent/container name in the property name is not adding value, I'd say. Think about the usage: Car myCar = new Car(e); What's more in myCar.CarEngine than simply myCar.Engine?
Dan C.
+4  A: 

For private members I always prefix with an underscore:

private Engine engine;

becomes:

private Engine _engine;

Whenever I see m_, it makes my stomach churn.

Kev
How do you differentiate between local variables and parameters?
Serhat Özgel
@buyutec: Differentiating between locals and parameters seems a bit overkill. Prefixing everything could reduce the benefits for a reader's eye.
Dan C.
@Dan - agreed, it's very rare you ever need to do that and if you do then you'd be working with something like newEngine, tempEngine or anotherEngine... in these scenarios to differentiate.
Kev
A: 

I don't like the Hungarian notation: m_foo, etc. I'm using the camel style: engine, myEngine, myBigEngine.

I would write exatly as you.

In MSDN I saw one remark: use public Car(Engine e) - I mean name input parameter something else as local variable. But I don't do that.

abatishchev
+3  A: 

Like this:

public class Car
{    
    #region fields

    private Engine _engine;

    #endregion

    #region public properties

    public Engine Engine { get { return _engine; } set { _engine = value; } }  

    #endregion 

    #region constructors 

    public Car(Engine engine)    
    { 
        _engine = engine; 
    }

    #endregion
}

Sadly the SO code stylesheet is eliding my blank lines, which make it a bit clearer and easier to read. The region directives, which we use on all production code, help avoid confusion. The underscore prefix is the only prefix I use (well, except for I on interfaces but everyone does that) but I do use it religiously, so we never confuse fields and locals (as in the contstructor). I see no major problem with having the property name and type name the same (in VS the highlighting will differentiate between them). It's only a problem if you try to use a static member or method of the type, and if you do then you'll either have to alias it or refer to it explicitly (ie MyNamespace.VehicleParts.Engine.StaticMethod()).

Seems readable to me, but it's all very subjective.

DotNetGuy
Agh! Regions! *averts eyes*
Garry Shutler
Agreeing with Garry. Hate Regions. They are a blight.
Chris Brandsma
I used to - but I've been converted :-)
DotNetGuy
Some say that region support had feature number 666 in C#))
Rinat Abdullin
A: 

It's ok to leave them as they are apart from one small thing. In intellisense, it's not immediately obvious whether an item is a parameter, local or private member as they all have the same symbol (blue cube). If, however, you move cursor to a particular item then the tooltip tells you which of these it is.

As a visual aid, you may want to prefix your private member with an underscore, _engine so that it's immediately obvious that it is a private member without having to move the cursor. This is a convention which I use and it is the only name I would change in your example.

AdamRalph
A: 
public class Car
{

    public Car(Engine engine)
    {
        Engine = engine;
    }

    public Engine Engine { get; set; }

}

If I had a field, I prefix it with an underscore (_). So private Engine engine; would turn into private Engine _engine;

Chris Brandsma