Introduction
Many of us has the habit of writing the programming logic as follows
Case 1:
int a = 5;
if (a == 6){
}
or Case 2:
bool x = false;
if (x == true){
}
That means we are using equality comparison operator to compare the values.But, if by mistake we write like
Case 1:
int a = 5;
if (a = 6){
}
or Case 2:
bool x = false;
if (x = true){
}
Then the whole purpose of conditional checking will be wrong.
I do agree that for the first case, C# will give a compilation error Cannot implicitly convert type 'int' to 'bool'
while for the second case the it leaves away by giving an warning Assignment in conditional expression is always constant;did you mean to use == instead of = ?
The Yoda style
A better way to write code in that case will be in the Yoda style as below
Case 1:
int a = 5;
if (6 == a){
}
or Case 2:
bool x = false;
if (true == x){
}
Why?Because it reduces coding errors where we unintentionally mistyped the comparison operator == as a single =
Case 1:
int a = 5;
if (6 = a){
}
or Case 2:
bool x = false;
if (true = x){
}
C# will give compilation error in both the cases as The left-hand side of an assignment must be a variable, property or indexer
In simple words,we can't assign a value to a literal
Usage of this conditions style was popular on C/C++ where we could assign value to variable when typed = instead of ==
Does it really needed in C#?
Well from all the above experiments (atleast Case 1), we have seen that in C# expressions are not converted automatically to bool and henceforth this practice does not make much sence in C# parlance
However,the convention should be to always put the constant on the left hand side of the expression so that an error can be statically detected at compile time in the event of a typo e.g. = (assignment) was coded instead of the == (equality).
How IL interpretes?
To answer this question, we have developed a simple program as under
public bool ConstantLeft(int a)
{
return a == 1;
}
public bool ConstantRight(int a)
{
return 1 == a;
}
When viewed in IL, we found the below for ConstantLeft() function
.method public hidebysig instance bool ConstantLeft(int32 a) cil managed
{
.maxstack 2
.locals init ([0] bool CS$1$0000)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4.1
IL_0003: ceq
IL_0005: stloc.0
IL_0006: br.s IL_0008
IL_0008: ldloc.0
IL_0009: ret
}
For ConstantRight() function, IL view is as under
.method public hidebysig instance bool ConstantRight(int32 a) cil managed
{
.maxstack 2
.locals init ([0] bool CS$1$0000)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: ldarg.1
IL_0003: ceq
IL_0005: stloc.0
IL_0006: br.s IL_0008
IL_0008: ldloc.0
IL_0009: ret
}
The IL infers that, line numbers IL_0001 and IL_0002, they're just swapped but the order of the operands doesn't change the behavior of ceq at IL_0003.So apart from swapping, there was no change found.
Reference
What are yoda conditions?
Conclusion
Hope this little tip will be helpful. Comments and suggestions are welcome.
Thanks for reading.