20

I have always thought it was "best practice" to be explicit in naming my collection variables. So, if I had a collection of Car objects, I would typically name a Car[] carArray and a List<Car> carList.

And then 99% of the time, I end up just doing something like...

foreach (Car car in carArray)
{
    ...
}

...and I'm thinking, I could have just called the array cars, and it wouldn't have made any difference.

And now that we have IEnumberable<T>, I'm actually faced with the question of whether I might consider writing something like carIEnumerable? or carEnumerable. So far, the answer has been "no".

My thinking here is that the type of collection often doesn't matter, and when it does, is still doesn't matter if the collection type is written into the variable name. I just had a case where I had to switch from an IEnumerable<Car> to a List<Car> because I needed "bracket access" to the items (e.g., carList[3]). In that case, the two collection types do not behave the same, but would naming the variable cars have been a problem here?

Not to add another layer of complexity to this question, what happens if I use var? E.g.,

var cars = GetCars();

I can certainly tell cars is some kind of collection. I can iterate it. If I'm using LINQ, I can use extension methods. More importantly, if I later change up the type of collection, there would be much less code to mess with. var would still be var and cars would still be cars. That seems very appealing to me, and I having trouble seeing much disadvantage.

So, just to make sure my question is clear: How do you name your collection variables and why? Is there a serious readability or clarity cost to just "pluralizing" the name of the item?

devuxer
  • 41,681
  • 47
  • 180
  • 292
  • 6
    Naming variables "carArray" is just using Hungarian notation. It's generally frowned upon as bad practise in C# apart from for UI controls. – RichardOD Aug 31 '09 at 21:00
  • 3
    Don't do it! The world will end if you named it cars instead of carArray! – Powerlord Aug 31 '09 at 21:07
  • Remember that you can access elements by number using ElementAt() on List et al. (I don't know why the brackets aren't availble for IEnumereables, but there's probably a good reason.) – Jan Aagaard Sep 07 '09 at 16:02
  • I think the brackets aren't there for IEnumerable because you aren't accessing that index the same way as with other collections, instead you iterate over it until you reach the nth element, which might involve any other operations and also doesn't happen in constant time. I'd say the brackets aren't there to make you aware of that fact. – Botz3000 Dec 04 '09 at 12:05
  • 1
    Yes, the flying spaghetti monster will chain you to the yoke and make you plough the world's oceans until the days end! On a serious note, why even ask, it's a totally natural thing to do, as long as your natural language has plurals. You will get stuck with superplurals, e.g. datum->data->datas->datases eventually, so I suggest using qualifiers, e.g. "SelectedCars" rather than "Cars." – Dima Tisnek Jun 12 '12 at 11:15

12 Answers12

36
var car = cars.Where(c => c.Name == "Robin Reliant");

Readability wins.

Hence I go with pluralizing.

Kindness,

Dan

Daniel Elliott
  • 22,647
  • 10
  • 64
  • 82
  • 8
    If readability truly wins, you would name the lambda variable "car" instead of "c". Also, the local variable is still a sequence, so instead of "car" you should pluralize it and indicate filtering has been applied, i.e. "robinReliantCars". – Bryan Watts Sep 01 '09 at 03:18
  • @Bryan, I agree with the second part of your comment. Perhaps the example should be changed to: `var car = cars.Where(c => c.Name == "Robin Reliant").First();`. As for using `car` in place of `c`, that might actually hurt readability because it's less succinct. In my experience with LINQ so far, I've found very short lambda variables to be quite readable. I follow a pretty consistent pattern: `cars` would be `c`, `reliableCars` would be `rc`, etc. Seems to work pretty well. – devuxer Sep 01 '09 at 16:54
  • @DanThMan, I find `car` more readable as I don't have to infer that `c == car` from context and then remember that every time I read `c`. And also that `rc` means `reliableCar` in one context and `rallyCar` in another. To each his own :-) – Bryan Watts Sep 02 '09 at 00:08
  • 2
    @Bryan, I think it's really a trade-off. You do have to rely on context to understand the meaning of something like "c", but with a LINQ expression, that context is always very close at hand. And I think the brevity improves readability, especially when you have a series of extension methods chained together, as in `var v6Sedans = cars.Where(c => c.Doors = 4 && c.Cylinders = 6).OrderBy(c => c.Make, c.Model);` You figure out what "c" is right off the bat because you know you're selecting from cars. After that, it just saves you a lot of typing and reading. – devuxer Sep 03 '09 at 05:10
  • What if you change context in the middle of your expression? `cars.Where(c => c.Doors == 4 && c.Cylinders == 6).OrderBy(c => c.Make).Select(c => c.Carburetor).Where(c => c.Old && c.NeedsRepair).OrderBy(c => c.ManufactureDate);` Your reliance on context is even greater now. I guess I don't equate brevity with readability. In fact, I generally see those 2 concepts at odds. There is always a price to pay for something "clever" like 1-character variable names - in this case I think it is ambiguity. – Bryan Watts Sep 04 '09 at 15:04
20

The problem with this kind of naming is that it concentrates too much on the actual implementation rather than the purpose of the property. Instead of CarArray, you could use OwnedCars, or whatever tells the user why that enumeration is there.

I think naming the loop variable "car" in a small foreach-loop is just fine.

If you write var cars = GetCars(), the compiler looks at the type on the right side of the assignment, in this case possibly IEnumerable<Car>, and gives cars that type. You can even see it in subsequent uses of the variable if you hover over it with your mouse.

If you change the type of a collection and don't have to change your code because you are using var, think about the fact that those different types of collections probably have something in common that enables you to perform the same operations on them. Probably it's IEnumerable if you use them in foreach loops.

So you could just as well expose those collections as IEnumerable, so users of your class don't depend too much on a certain implementation.

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • +1 was just about to type something similar about using implicit declarations with var and how the name and type can stay the same till the return value logic is determined. Very convenient. – Ahmad Mageed Aug 31 '09 at 21:16
12

I never liked the "put the type of the variable in its name" approach - I really think it interferes with the smooth reading of the source. I believe code should be read like a story, and so it makes perfect sense to me that a group of cars (and I don't care if its implemented as an array, a linked list, a heap, set or whatever) is named "Cars":

foreach (Car currentCar : ParkingLog.getCars()) {
    stolenCars.add(currentCar);    
}

fencer.cars = stolenCars;

Works for me.

Guss
  • 30,470
  • 17
  • 104
  • 128
12

Personally I avoid using the type of the collection in the variable name whenever possible. It may look nice but it's an un-enforcable constraint that other developers will mess up over time. If the type of the variable is really important for a particular operation I would instead consider rewriting the code to be ...

  1. Less concerned about the specific collection implementation
  2. Make the code shorter / more concise to the point the type of the variable is unambiguous

Or in other words, I don't like Hungarian notation.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
12

I generally start by pluralizing (e.g. cars). Often you will also have a local variable in the singular form (e.g. car), sometimes it can be awkward to read the code with two very similar variable names in which case I will find a new name for one of the variables.

I almost never would use carArray, more likely allCars, or selectedCars or something appropriate.

ScottS
  • 8,455
  • 3
  • 30
  • 50
12

Prefer cars to carArray, but cars probably isn't what you want either. Which cars?

  • allCars
  • redCars
  • brokenCars
  • carsWith3Axels

In all but a few cases (there are always those pesky exceptions) variable names like cars are not descriptive enough.

Matthew Vines
  • 27,253
  • 7
  • 76
  • 97
5

You certainly shouldn't add the type name as part of the variable name - pretty much for the reason you mentioned. Personally, if I had a collection of Car objects I'd just call the collection Cars - the plural conveys the fact there are more than one without revealing the type, which is unnecessary.

Dan Diplo
  • 25,076
  • 4
  • 67
  • 89
5

I've been naming my variables things that include the variable type, as part of learning. It's helpful for me to see carArray somewhere in the code as a reminder that it's the array. But your question brings up a very valid point in that if you change that later, you then have to chase down all those references and that can be a big nightmare. I am seeing the wisdom of naming variables according to Matthew Vines' answer, "allCars," "brokenCars." I think I will do that more often from here on out, as my coding improves.

JYelton
  • 35,664
  • 27
  • 132
  • 191
3

Putting the collection type in the variable name is a problem when maintenance leads you to change the type. Using pluralization, or something generic like 'carColl' is simpler. It gets the point across without being something that a future change would need to affect.

krdluzni
  • 799
  • 2
  • 9
  • 10
2

I'm thinking, I could have just called the array cars, and it wouldn't have made any difference.

Nope, doesn't make a difference to the compiler, but using descriptive names helps with readability, maintainability, and reuse.

In Visual Studio, I can quickly find the data type. Therefore, I use complete descriptive names. Plurals are fine. If the plural seems awkward then I append Listing or whatever is needed to indicate the variable contains a "collection".

For example, carArray means nothing to me. Is car an abbreviation? What if you change the implementation of carArray into a IList or IEnumerable of Car objects? Does that mean you change the name of the variable, or leave the name as it is? Too much to think about. Yet, I would understand Cars, CarListing, CarList, CarsByModel, and so on.

AMissico
  • 21,470
  • 7
  • 78
  • 106
1

I think using the plural makes perfect sense, and that's the method I generally use in my code. I've never found that having the data type as part of the variable name is all that helpful.

Dave Carlile
  • 7,347
  • 1
  • 20
  • 23
-4

The difference between "cars" and "carArray" is the self documenting nature of the code. No need to figure out what type of collection you are using if it's built into the name. In a trivial program, it doesn't really matter, but in something more significant the time savings are important.

jmq
  • 10,110
  • 16
  • 58
  • 71
  • 4
    Self-documenting is rather pointless in this kind of case. Any good IDE can tell you what the type is immediately, so writing code against it isn't any harder. And what happens if you want to change the type later? Maybe a different type would be more efficient. If you embed the type in the name you have to rename it or be inconsistent. I honestly see no benefit to embedding the type in the name. – Herms Aug 31 '09 at 21:05
  • What about when maintenance causes you to change the type? And programming to an interface rather than a class? – krdluzni Aug 31 '09 at 21:06
  • 1
    Until someone changes array to a list, and neglects to rename the variable. When quickly scanning code I find it is usually enough to understand something is a collection of some sort. Most methods should be small enough that it is easy to glance at the declaration if more info is needed. Modern IDEs make determining type even easier. When actually editing code the time saved by including the type in the name is a micro-optimization on a long running process. – ScottS Aug 31 '09 at 21:12
  • I wasn't trying to make a value judgment, but to try and point out why one may be picked over the other. I also should have said "could be" instead of "are" important. Personally, I would never just change the type like this to switch from one to the other. It's making the assumption that the new type will work just like the old type (for the simple builtins it's not really an issue). If I'm forced to deal with the name then I'm also forced to think about the impacts of my changes. JMHO. – jmq Aug 31 '09 at 21:43