The code
public class Exemplo {
public static void Main(string[] args) {
var x = 0;
if (x == 1) {
x = 1;
} else {
x = 2;
}
}
}
is compiled to
.method public hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 22 (0x16)
.maxstack 2
.locals init (
[0] int32,
[1] bool
)
IL_0000: nop // Do nothing (No operation)
IL_0001: ldc.i4.0 // Push 0 onto the stack as int32
IL_0002: stloc.0 // Pop a value from stack into local variable 0
IL_0003: ldloc.0 // Load local variable 0 onto stack
IL_0004: ldc.i4.1 // Push 1 onto the stack as int32
IL_0005: ceq // Push 1 (of type int32) if value1 equals value2, else push 0
IL_0007: stloc.1 // Pop a value from stack into local variable 1
IL_0008: ldloc.1 // Load local variable 1 onto stack
IL_0009: brfalse.s IL_0011 // Branch to target if value is zero (false), short form
IL_000b: nop // Do nothing (No operation)
IL_000c: ldc.i4.1 // Push 1 onto the stack as int32
IL_000d: stloc.0 // Pop a value from stack into local variable 0
IL_000e: nop // Do nothing (No operation)
IL_000f: br.s IL_0015 // Branch to target, short form
IL_0011: nop // Do nothing (No operation)
IL_0012: ldc.i4.2 // Push 2 onto the stack as int32
IL_0013: stloc.0 // Pop a value from stack into local variable 0
IL_0014: nop // Do nothing (No operation)
IL_0015: ret // Return from method, possibly with a value
} // end of method Exemplo::Main
Can be observed in the Sharplab.
And the code
public class Exemplo {
public static void Main(string[] args) {
var x = 0;
x = (x == 1 ? 1 : 2);
}
}
is compiled to
.method public hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 13 (0xd)
.maxstack 2
.locals init (
[0] int32
)
IL_0000: nop // Do nothing (No operation)
IL_0001: ldc.i4.0 // Push 0 onto the stack as int32
IL_0002: stloc.0 // Pop a value from stack into local variable 0
IL_0003: ldloc.0 // Load local variable 0 onto stack
IL_0004: ldc.i4.1 // Push 1 onto the stack as int32
IL_0005: beq.s IL_000a // Branch to target if equal, short form
IL_0007: ldc.i4.2 // Push 2 onto the stack as int32
IL_0008: br.s IL_000b // Branch to target, short form
IL_000a: ldc.i4.1 // Push 1 onto the stack as int32
IL_000b: stloc.0 // Pop a value from stack into local variable 0
IL_000c: ret // Return from method, possibly with a value
} // end of method Exemplo::Main
Can be observed in the Sharplab.
Therefore there is difference. The difference is only syntactic. But in previous version of this reply there was no difference. So it is implementation detail, can change from one version to another.
Contrary to popular belief, the version using the conditional operator may be more efficient.
But it’s not that simple. This may not be valid in other situations. I made a simple example. The only way to know what’s really going to happen and if it’s going to have the same performance is to measure it. It is checking whether to generate the same code in its exact real situation in the compiler version that is used.
And what’s more, the Jitter can make more optimizations and reverse the situation or leave under the same conditions.
See another example of comparison in English.
You can check the raw IL code with the ildasm.exe that comes with Visual Studio, or you can use another decompiler like Ilspy, the dotPeek, the .NET Reflector or the Justdecompile.
You must choose what is better to give understanding for what you want. If you need to use a conditional operator in a complex expression it can become unreadable. On the other hand create multiple lines in one if
to do a simple operation can also be an exaggeration. A hint to improve the readability of the conditional operator and to make it clear that you are mounting an expression is to place parentheses around the complete expression (the three operands as one thing). Of course there are situations that even this does not help.
If there is side effect (change of status), this needs to be clear in the code. It seems to me that in the cases I have presented this is clear. But there are cases where the code can make it difficult to read the side effect. You should avoid hiding possible misunderstandings in the code. The ternary operator is more prone to this. But neither should we run away from it at all costs. Relevance should be observed in the specific case.
Good example:
int resultado = Check() ? 1 : 0;
Bad example:
int resultado = Check1() ? 1 : Check2() ? 1 : Check3() ? 1 : 0;
Although this example can be improved:
int resultado = Check1() ? 1 :
Check2() ? 1 :
Check3() ? 1 :
0;
One of the advantages of using the conditional operator instead of the if
is the reduction of duplicate code. It is good to keep the concision. But this must not be to the detriment of the readability of the code. More performance for one side or the other is no advantage. The gain will certainly be small even in the most extraordinary situations. If you really need this possible small performance gain, C# is not the appropriate language.
The Resharper is a great tool (almost mandatory) and gives great suggestions, but it does not code for you. The programmer is always needed to give context to the code. Resharper is no smarter than you and he doesn’t know if his code is really going to get any better the way he suggests. He hints, you decide.
I put in the Github for future reference.
The difference is in readability... not that one is more than the other, but that, in certain situations, one is more readable than the other.
– Miguel Angelo
As I know Resharper analyzes the "simplicity" of the if and suggests the expression "?:" to replace the if. I believe you’ve won in performance, yes, but nothing that significant. But consider one thing, analyze the full reading of your code and see if it is readable to other programmers. The excessive use of this expression can cause confusion in the reading of the code, hindering a future reading for maintenance in the application.
– Matheus Bessa
agree, not always the ?: helps readability, in the example above I think begins the limit that does not compensate for the use of it. usually use for something simple like Return (id == null ? 0 : id);
– Dorathoto
In that case, to decrease code could just remove the keys
– LucasMotta
@Dorathoto you should have left the reward 1 week to highlight your question.
– Maniero
But your answer is already 100% good...
– Dorathoto