Video: High-Quality Code - Use of Variables, Data, Expressions and Constants (Bulgarian)
February 08, 2021
Nikolay Kostov (Nikolay.IT)
Topics covered:
Principles for Initialization
Scope, Lifetime, Span
Using Variables
Variables Naming
Naming convention
Standard Prefixes
Using Expressions
Using Constants
Video (in Bulgarian)
Presentation Content
Initially Assigned Variables in C#
Static variables
Instance variables of class instances
Array elements
Value parameters
Reference parameters
Variables declared in a catch clause or a foreach statement
Initially Unassigned Variables in C#
Output parameters
Including the this variable of struct instance constructors
Local variables
Except those declared in a catch clause or a foreach statement
Guidelines for Initializing Variables
When the problems can happen?
The variable has never been assigned a value
The value in the variable is outdated
Part of the variable has been assigned a value and a part has not
E.g. Student class has initialized name, but faculty number is left unassigned
Developing effective techniques for avoiding initialization problems can save a lot of time
Variable Initialization
Initialize all variables before their first usage
Local variables should be manually initialized
Declare and define each variable close to where it is used
This C# code will result in compiler error:
intvalue;
Console.WriteLine(value);
We can initialize the variable at its declaration:
intvalue = 0;
Console.WriteLine(value);
Pay special attention to counters and accumulators
A common error is forgetting to reset a counter or an accumulator
int sum = 0;
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
sum = sum + array[i, j];
}
Console.WriteLine(
"The sum of the elements in row {0} is {1}", sum);
}
The sum must be reset after the end of the inner for loop
Check the need for reinitialization
Make sure that the initialization statement is inside the part of the code that’s repeated
Check input parameters for validity
Before you assign input values to anything, make sure the values are reasonable
int input;
bool validInput =
int.TryParse(Console.ReadLine(), out input);
if (validInput)
{
…
}
Partially Initialized Objects
Ensure objects cannot get into partially initialized state
Make all fields private and require valid values for all mandatory fields in all constructors
Example: Student object is invalid unless it has Name and FacultyNumber
Somewhere between the lengths of x and maximumNumberOfPointsInModernOlympics
Optimal length – 10 to 16 symbols
Too long
numberOfPeopleOfTheBulgarianOlympicTeamFor2012
Too short
а, n, z
Just right
numTeamMembers, teamMembersCount
Naming Specific Data Types
Naming counters
UsersCount, RolesCount, FilesCount
Naming variables for state
ThreadState, TransactionState
Naming temporary variables
Bad examples:
a, aa, tmpvar1, tmpvar2
Good examples:
index, value, count
Name Boolean variables with names implying “Yes / No” answers
canRead, available, isOpen, valid
Booleans variables should bring “truth” in their name
Bad examples:
notReady, cannotRead, noMoreData
Good examples:
isReady, canRead, hasMoreData
Naming enumeration types
Use build in enumeration types (Enum)
Color.Red, Color.Yellow, Color.Blue
Or use appropriate prefixes (e.g. in JS / PHP)
colorRed, colorBlue, colorYellow
Naming constants – use capital letters
MAX_FORM_WIDTH, BUFFER_SIZE
C# constants should be in PascalCase:
Int32.MaxValue, String.Empty, InvariantCulture
Naming Convention
Some programmers resist to followstandards and conventions
But why?
Conventions benefits
Transfer knowledge across projects
Helps to learn code more quickly on a new project
Avoid calling the same thing by two different names
When should we use a naming convention?
Multiple developers are working on the same project
The source code is reviewed by other programmers
The project is large
The project will be long-lived
You always benefit from having some kind of naming convention!
Language-Specific Conventions
C# and Java / JavaScript conventions
i and j are integer indexes
Constants are in ALL_CAPS separated by underscores (sometimes PascalCase in C#)
Method names use uppercase in C# and lowercase in JS for the first word
The underscore _ is not used within names
Except for names in all caps
Standard Prefixes
Hungarian notation – not used
Semantic prefixes (ex. btnSave)
Better use buttonSave
Do not miss letters to make name shorter
Abbreviate names in consistent way throughout the code
Create names, which can be pronounced(not like btnDfltSvRzlts)
Avoid combinations, which form another word or different meaning (ex. preFixStore)
Kinds of Names to Avoid
Document short names in the code
Remember, names are designed for the people, who will read the code
Not for those who write it
Avoid variables with similar names, but different purpose
UserStatus / UserCurrentStatus
Avoid names, that sounds similar
decree / degree / digRee
Avoid digits in names
Avoid words, which can be easily mistaken
E.g. adsl, adcl, adctl, atcl
Avoid using non-English words
Avoid using standard types and keywords in the variable names
E.g. int, class, void, return
Do not use names, which has nothing common with variables content
Avoid names, that contains hard-readable symbols / syllables, e.g. Csikszentmihalyi
Avoid Complex Expressions
Never use complex expressions in the code!
Incorrect example:
for (int i=0; i<xCoords.length; i++) {
for (int j=0; j<yCoords.length; j++) {
matrix[i][j] =
matrix[xCoords[findMax(i)+1]][yCoords[findMin(j)-1]] *
matrix[yCoords[findMax(j)+1]][xCoords[findMin(i)-1]];
}
}
Complex expressions are evil because:
Make code hard to read and understand, hard to debug, hard to modify and hard to maintain What shall we do if we get at this line IndexOutOfRangeException? There are 10 potential sources of IndexOutOfRangeException in this expression!
Simplifying Complex Expressions
for (int i = 0; i < xCoords.length; i++)
{
for (int j = 0; j < yCoords.length; j++)
{
int maxStartIndex = findMax(i) + 1;
int minStartIndex = findMin(i) - 1;
int minXcoord = xCoords[minStartIndex];
int maxXcoord = xCoords[maxStartIndex];
int minYcoord = yCoords[minStartIndex];
int maxYcoord = yCoords[maxStartIndex];
int newValue =
matrix[maxXcoord][minYcoord] *
matrix[maxYcoord][minXcoord];
matrix[i][j] = newValue;
}
}
Avoid Magic Numbers and Strings
What is magic number or value?
Magic numbers / values are all literals different than 0, 1, -1, null and "" (empty string)
Avoid using magic numbers / values
They are hard to maintain
In case of change, you need to modify all occurrences of the magic number / constant