这两个陈述是否相同?

JL.*_*JL. 6 c# if-statement

以下2个代码片段是否实现了相同的功能?

我原来的代码:

if (safeFileNames != null)
{
    this.SafeFileNames = Convert.ToBoolean(safeFileNames.Value);
}
else
{
    this.SafeFileNames = false;
}
Run Code Online (Sandbox Code Playgroud)

ReSharper认为是一个更好的主意:

this.SafeFileNames = safeFileNames != null && 
                     Convert.ToBoolean(safeFileNames.Value);
Run Code Online (Sandbox Code Playgroud)

我认为上面的代码更容易阅读,任何令人信服的理由改变它?
它会执行得更快,最重要的是,代码会执行完全相同的操作吗?

另外,如果你看看:Convert.ToBoolean(safeFileNames.Value);部分,那么肯定会导致空引用异常?

this.SafeFileNames = bool
Run Code Online (Sandbox Code Playgroud)

本地safeFileNames是一个强类型的自定义对象,这里是类:

public class Configuration
    {
        public string Name
        {
            get;
            set;
        }
        public string Value
        {
            get;
            set;
        }
    }
Run Code Online (Sandbox Code Playgroud)

Dav*_*eer 24

你问这个问题的事实告诉我,前者是首选的.也就是说,在我看来,你的问题意味着你相信第一个代码更容易理解,而你不确定第二个代码是否相同.软件设计的主要目标是管理复杂性.如果它现在让你感到困惑,也可能是你以后或者任何支持你的代码的人.

  • 这是一个很好的答案. (4认同)

Bri*_*ntz 5

这两个陈述完全相同.使用哪个是优先考虑的问题,但我更喜欢Resharper的版本.更简洁,移动部件更少.更容易看到代码的意图.


jvi*_*lta 5

这是两段代码的IL.我拿了你的代码并创建了一个控制台应用程序来查看IL.从结果IL中可以看出,一个方法(method2)缩短了4个字节,但两个运行的IL几乎相同,所以就性能而言......不用担心.它们都具有相同的性能.更多地关注哪一个更容易阅读,更好地展示您的意图.

我的代码:

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; }
}
Run Code Online (Sandbox Code Playgroud)

方法1的IL:

.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
Run Code Online (Sandbox Code Playgroud)

方法2的IL:

.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
Run Code Online (Sandbox Code Playgroud)