因为我有
public class Foo
{
public int? Id { get; set; }
}
什么更好
if ((Id ?? 0) == 0) {}
或
if (Id == null || Id == 0)
答案 0 :(得分:4)
我推荐第二个。它更具可读性。
正如我所注意到的,很少有人熟悉??
运营商。
答案 1 :(得分:4)
if(Id.GetValueOrDefault() == 0)
也是一种选择。在性能方面,我怀疑是否存在任何真正的差异,无论如何你都会进行微优化,这很少有益。
答案 2 :(得分:2)
我每次都喜欢可读性而不是聪明(几乎),所以我肯定会选择:if (Id == null || Id == 0)
答案 3 :(得分:2)
更好的是:
if(!Id.HasValue || Id == 0)
{
}
答案 4 :(得分:2)
由于这是标记为“性能”,这里是我对这些主题的一般建议,我认为这些主题在这里是有效的:
扩展:
您的代码中可能存在一些使得此类微优化提示无效或非最佳的内容,因此您在性能方面的最佳选择就是衡量它。确保你测量一个循环的足够迭代,因为测量小代码1次会受到你的机器使整个运动无效的所有其他事情的干扰。
对于微优化,不要担心。选择你(以及其他任何人将要维护代码)的人最为舒适,并且如果你真的需要,那么就要担心微观优化。
我个人经常写第一个,即
if (o ?? 0 == 0)
或者,对于字符串:
if ((s ?? string.Empty).Length == 0)
然而,就可读性和“看起来最好”而言,这是一个双重问题。随心所欲,随心所欲,继续探讨更大的问题。
编辑,好吧,在最后一个代码示例之前,我在某处停止思考。我结合了两件不同的事情:
null
if (PropertyName.Length == 0)
当然,在该特定示例中,我将使用以下两种方法之一:
if (string.IsNullOrEmpty(s))
if (string.IsNullOrWhiteSpace(s))
(仅限4.0,仅在您需要时)答案 5 :(得分:1)
如果您正在使用此代码一次,那么使用它的区别并不大(但是,我更喜欢第二个 - 它更具可读性)。否则,我想给出一些我在这里验证的条件名称。 E.g。
public class Foo
{
public int? Id { get; set; }
public bool IsNew
{
get
{
return (Id == null) || (Id == 0);
}
}
}
现在代码说出你要验证的内容。它可以像书一样阅读
if (IsNew) {}
答案 6 :(得分:1)
我认为在你的情况下,第一个例子可以快一点。
我在LinqPad中以两种方式做到了这一点
void Main()
{
Foo f = new Foo();
if ((Id ?? 0) == 0) {} // if (f.Id == null || f.Id == 0) {}
}
// Define other methods and classes here
public class Foo
{
public int? Id { get; set; }
}
if ((Id ?? 0) == 0) {}
的IL如下:
IL_0000: newobj UserQuery+Foo..ctor
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: callvirt UserQuery+Foo.get_Id
IL_000C: stloc.1
IL_000D: ldloca.s 01
IL_000F: call System.Nullable<System.Int32>.get_HasValue
IL_0014: brtrue.s IL_0019
IL_0016: ldc.i4.0
IL_0017: br.s IL_0020
IL_0019: ldloca.s 01
IL_001B: call System.Nullable<System.Int32>.GetValueOrDefault
Foo.get_Id:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery+Foo.<Id>k__BackingField
IL_0006: ret
Foo.set_Id:
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld UserQuery+Foo.<Id>k__BackingField
IL_0007: ret
Foo..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ret
if (f.Id == null || f.Id == 0)
的IL低于 - 请注意两次调用get_HasValue
IL_0000: newobj UserQuery+Foo..ctor
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: callvirt UserQuery+Foo.get_Id
IL_000C: stloc.1
IL_000D: ldloca.s 01
IL_000F: call System.Nullable<System.Int32>.get_HasValue
IL_0014: brfalse.s IL_0031
IL_0016: ldloc.0
IL_0017: callvirt UserQuery+Foo.get_Id
IL_001C: stloc.2
IL_001D: ldloca.s 02
IL_001F: call System.Nullable<System.Int32>.GetValueOrDefault
IL_0024: brtrue.s IL_002F
IL_0026: ldloca.s 02
IL_0028: call System.Nullable<System.Int32>.get_HasValue
IL_002D: br.s IL_0030
IL_002F: ldc.i4.0
Foo.get_Id:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery+Foo.<Id>k__BackingField
IL_0006: ret
Foo.set_Id:
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld UserQuery+Foo.<Id>k__BackingField
IL_0007: ret
Foo..ctor:
IL_0000: ldarg.0
IL_0001: call System.Object..ctor
IL_0006: ret
也许我应该多出更多!
答案 7 :(得分:-2)
我建议第二个也应该优先考虑以下代码
if (null == Id || 0 == Id)