Are these 2 statements the same?

Do the following 2 code snippets to achieve the same?

My source code:

if (safeFileNames != null) { this.SafeFileNames = Convert.ToBoolean(safeFileNames.Value); } else { this.SafeFileNames = false; } 

What ReSharper thought was the best idea:

 this.SafeFileNames = safeFileNames != null && Convert.ToBoolean(safeFileNames.Value); 

I think the above code is much easier to read, any good reason to change it?
Will it run faster, and most importantly, will the code do the same?

Also, if you look at the section: Convert.ToBoolean(safeFileNames.Value); , then this can lead to the exclusion of a null reference?

 this.SafeFileNames = bool 

Local safeFileNames is a strongly typed user object, here is a class:

 public class Configuration { public string Name { get; set; } public string Value { get; set; } } 
+6
c # if-statement
source share
8 answers

The fact that you asked this question tells me that the former is preferable. That is, it seems to me that your question implies that you think that the first code is easier to understand, and you are not entirely sure that the second is equivalent. The primary goal of software development is complexity management. If this confuses you now, it may be for you later, or for those who support your code along the way.

+24
source share

Both statements do the same. For use, this is a matter of preference, but I prefer the Resharper version. More compressed, less mobile parts. It’s easier to see the intention of the code.

+5
source share

Here is the IL for both parts of the code. I took your code and created a console application to take a look at IL. As you can see from the final IL, one method (method2) is 4 bytes shorter, but the IL, which works for both, is almost the same as the performance goes on ... don't worry about that. They will both have the same performance. Focus more on what is easier to read and better demonstrates your intentions.

My code is:

 class Program { static void Main(string[] args) { } public void method1() { bool? safeFileNames = null; if (safeFileNames != null) { SafeFileNames = Convert.ToBoolean(safeFileNames.Value); } else { SafeFileNames = false; } } public void method2() { bool? safeFileNames = null; SafeFileNames = safeFileNames != null && Convert.ToBoolean(safeFileNames.Value); } public static bool SafeFileNames { get; set; } } 

IL for method 1:

 .method public hidebysig instance void method1() cil managed { // Code size 42 (0x2a) .maxstack 1 .locals init ([0] valuetype [mscorlib]System.Nullable`1<bool> safeFileNames) IL_0000: ldloca.s safeFileNames IL_0002: initobj valuetype [mscorlib]System.Nullable`1<bool> IL_0008: ldloca.s safeFileNames IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1<bool>::get_HasValue() IL_000f: brfalse.s IL_0023 IL_0011: ldloca.s safeFileNames IL_0013: call instance !0 valuetype [mscorlib]System.Nullable`1<bool>::get_Value() IL_0018: call bool [mscorlib]System.Convert::ToBoolean(bool) IL_001d: call void ConsoleApplication5.Program::set_SafeFileNames(bool) IL_0022: ret IL_0023: ldc.i4.0 IL_0024: call void ConsoleApplication5.Program::set_SafeFileNames(bool) IL_0029: ret } // end of method Program::method1 

IL for method2:

 .method public hidebysig instance void method2() cil managed { // Code size 38 (0x26) .maxstack 1 .locals init ([0] valuetype [mscorlib]System.Nullable`1<bool> safeFileNames) IL_0000: ldloca.s safeFileNames IL_0002: initobj valuetype [mscorlib]System.Nullable`1<bool> IL_0008: ldloca.s safeFileNames IL_000a: call instance bool valuetype [mscorlib]System.Nullable`1<bool>::get_HasValue() IL_000f: brfalse.s IL_001f IL_0011: ldloca.s safeFileNames IL_0013: call instance !0 valuetype [mscorlib]System.Nullable`1<bool>::get_Value() IL_0018: call bool [mscorlib]System.Convert::ToBoolean(bool) IL_001d: br.s IL_0020 IL_001f: ldc.i4.0 IL_0020: call void ConsoleApplication5.Program::set_SafeFileNames(bool) IL_0025: ret } // end of method Program::method2 
+5
source share

This reduces the cyclic complexity of your code with the resharper clause.

It is easier to read or not, it is a personal opinion, but I prefer that the proposal you proposed give you.

They are identical, and if you want to read, I can also suggest the following:

 if (safeFileNames != null) this.SafeFileNames = Convert.ToBoolean(safeFileNames.Value); else this.SafeFileNames = false; 

or

 this.SafeFileNames = safeFileNames != null ? Convert.ToBoolean(safeFileNames.Value) : false 
+2
source share
They are the same. && is a short-circuited operator, so the second half of the expression will not evaluate whether safeFileNames is null.
+1
source share

They are the same. In one insert, if the first condition is not fulfilled, the second is not evaluated. This way you will not get a null link.

I am sure that IL is the same in both cases.

I prefer the second version.

+1
source share

Yes, both of these statements will do the same, you don’t need to accept offers of re-points as the gospel, which one person considers to be readable code, this is another mess.

There are several other ways to do what you are trying to do, which can be more readable, what type of value is safeFileNames? Looks like it could be a nullable bool? If so, you can simply write

 this.SafeFileNames = safeFileNames.GetValueOrDefault(); 
+1
source share

Logically, they are identical. Any performance difference is likely to be careless. It is possible that the second form translates to more efficient binary code on some platforms, as the second form eliminates the conditional. Conditional (incorrect speculative execution) can ruin your pipeline of processor instructions in work with an intensive processor. However, IL and JITTER must emit code of adequate quality so that it matters.

I agree with your understanding of readability, but I do not assume that everyone shares this.

0
source share

All Articles