In programming, there’s a lot you just learn from mistakes- errr, I mean experience. As a gift to all my young Padawans, I put together a list of my best programming secrets as well as a few things to avoid.
I’ll admit, 99% of these are my own opinion, but I’ve been doing this a lot longer than most so listen up! These tips are geared toward C# programmers, but the principles can apply to any language.
This is your prime directive. Memorize it, frame it, tattoo it on your arm… whatever you have to do. In practice, this means:
This is your secondary directive. Use helpful comments and name variables to help the poor slob reading your code 2 years from now to quickly understand what is going on. That poor slob just might be you. And trust me, 2 years later, the brain cells that wrote that code are long gone.
* System returns the values with the units-per-volt already calculated
* we only need to convert the units from kPa to PSI,
* and the time to whole milliseconds rather than fractions of a second.
*/
ORM Frameworks are great, but there are multiple ways to accomplish things in it and it can be confusing. I chose the functional programming approach rather than the "psuedo-SQL" approach. For example:
UNIT_COMMITTED uc = ctx.UNIT_COMMITTED.FirstOrDefault(u =>
u.SEQUENCE_NUMBER == CurrentUnit.SequenceNumber);
Instead of
UNIT_COMMITTED uc = from u in ctx.UNIT_COMMITTED
where u.SEQUENCE_NUMBER == CurrentUnit.SequenceNumber
select u;
Use functional programming to eliminate intermediate steps where it makes sense. Double check places where you use a foreach loop to see if it can be replaced with a LINQ extension. Here’s a before and after using LINQ:
Query with a loop
var uc = from u in ctx.UNIT_COMMITTED
where u.SEQUENCE_NUMBER == CurrentUnit.SequenceNumber
select u;
List<string> unitsForTest = new List<string>();
foreach (UNIT_COMMITTED unit in uc) {
if (unit.UNIT_STATUS == "PRELOG")
unitsForTest.Add(unit.SERIAL_NUMBER);
}
Functional approach
List<string> unitsForTest = ctx.UNIT_COMMITTED.Where(u =>
u.SEQUENCE_NUMBER == CurrentUnit.SequenceNumber
&& u.UNIT_STATUS == "PRELOG")
.OrderBy(u => u.SERIAL_NUMBER)
.Select(u => u.SERIAL_NUMBER)
.ToList();
This has the advantage of eliminating all that boilerplate code, plus the List is returned sorted. Organizing your code functionally may take some getting used to, but it pays off in the long run. You’ll have less bugs and it will be easier to modify down the road.
Stop saying, “Oh I’ll fix that later,” or “I’ll get to it next release.” I can’t count the times I’ve seen quick and dirty code labeled “temporary” still in use years later. This is bad technical debt.
However, there are times you may have to use some ugly code to get the job done. This is reasonable debt. Let’s look at an example.
Say you have a project that requires a data validation step that has about 6 sanity checks on the results. Being a sharp programmer, you know that the best method is to design a rules engine for validation. It would be flexible, extensible and awesome! BUT doing that that will greatly exceed time and budget. So, you quickly write some code that does the job but stays within budget.
In cases like this, leave a comment block that states:
Gold plating means adding features no one asked for just to make the product “shiny”. We all do it at times. Regardless of how useful it is, if you add it, you have to support it. This can be a fine line to tread.
In the C# world, the decimal data type is often overlooked in favor of a float or double. Many times, what you really want is a number that has 4 digits after the decimal point. Use a decimal type!
A float/double is an approximation of a value, while decimal is exact. (Decimal 5.0275 always stays 5.0275. You won't suddenly find it as 5.0274999999999.) This applies to your database as well. Don’t use a real when what you really want is a numeric(18,4). Use the correct data type to do the job.
Using var is often lazy, with a few exceptions. Admittedly, it’s about readability rather than correctness. However, if you use a declared type now, when you read your code again in 2 years, you won’t have to wonder what the variable is.
When you get the task of re-writing hopelessly bad code, stay focused and use a strategic approach.
That’s all, folks! I hope you found this list useful. If you’re feeling generous, leave a comment below about something you learned the hard way so we can all benefit!