C# 快速退出方法或构造函数是否有好处?
我相信这部分与短路逻辑有关,但我找不到任何直接回答我问题的问题。可能的相关问题: 考虑以下两个代码块,它们都是类的可能构造函数C# 快速退出方法或构造函数是否有好处?,c#,constructor,short-circuiting,C#,Constructor,Short Circuiting,我相信这部分与短路逻辑有关,但我找不到任何直接回答我问题的问题。可能的相关问题: 考虑以下两个代码块,它们都是类的可能构造函数 public MyClass(OtherClass other){ if (other != null) { //do something with other, possibly default values in this object } } 还有这个 public MyClass(OtherClass other){ if
public MyClass(OtherClass other){
if (other != null) {
//do something with other, possibly default values in this object
}
}
还有这个
public MyClass(OtherClass other){
if (other == null) return;
//do something with other, possibly default values in this object
}
做后者比做前者有什么好处吗?构造函数中没有其他代码,只有使用
other
对象来构造此对象的代码。唯一的区别是可读性。通过您所谓的“快速退出”,您可以停止思考您所处的条件,因为您已不再处于条件中。在这种情况下,您应该做您和您的同事最容易理解的事情。两种方法之间不太可能存在任何可察觉的速度差异 后者通常更容易阅读,如果您有多个终止案例,那么它会变得更容易。但是,没有速度差
假设您有一个接受Int32?
的函数,如果该值为null
,偶数
,或大于100,则该函数将退出
你可以
void fn( Int32? num ) {
if ( num != null ) {
if ( num < 100 ) {
if ( num % 2 != 1 ) {
//method code
现在这个例子有点傻,我现在能听到你说的,为什么不把它们和
|
或&&
放在一行,在这种情况下是的。但是想象一下,如果数据验证比这复杂得多呢?最终,代码会过度缩进,更难阅读。这都是关于代码库中的可读性和一致性。如果一个长方法的返回值到处都是,那么它将很难被读取(但是一个长方法无论如何都是不好的)。方法开头的几个保护子句可以提高清晰度并删除不必要的嵌套。然而,在您给出的特定示例中,您必须询问“为什么这里可以使用null?”您应该抛出异常还是传入异常?可读性是最大的区别。在这种情况下,后者导致较少的压痕,有些可能认为更可读。我还认识一些开发人员,他们坚信方法应该只有一个返回语句。这些开发人员显然更喜欢前者。特别是在这种情况下,虽然您(假设您是人类)需要通读其余的源代码才能完成方法,但处理器不需要。第一个示例中的blockif
语句对条件求值,如果求值为false,则执行将跳到方法的末尾。我尝试使用此构造函数
public AnotherExpense(string param)
{
if (param != null)
{
Console.WriteLine("test");
}
}
IL码
.method public hidebysig specialname rtspecialname
instance void .ctor(string param) cil managed
{
// Code size 20 (0x14)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void AccountParserCSV.Expense::.ctor()
IL_0006: ldarg.1
IL_0007: brfalse.s IL_0013
IL_0009: ldstr "test"
IL_000e: call void [mscorlib]System.Console::WriteLine(string)
IL_0013: ret
} //
如果你把它改成
public AnotherExpense(string param)
{
if (param == null)
return;
Console.WriteLine("test");
}
你得到
.method public hidebysig specialname rtspecialname
instance void .ctor(string param) cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void AccountParserCSV.Expense::.ctor()
IL_0006: ldarg.1
IL_0007: brtrue.s IL_000a
IL_0009: ret
IL_000a: ldstr "test"
IL_000f: call void [mscorlib]System.Console::WriteLine(string)
IL_0014: ret
}
参见第7行的“差异”;-)
编辑-使用VS2010在“发布”中编译这也是我的想法。只是想看看这样做是否有性能(或任何其他)优势。在这个特定的例子中,null是可以的,因为它们是asp.net mvc中视图模型的方便构造函数。如果来自服务层的数据库模型返回为null(创建“Save”版本的可能性很大),那么视图模型将为空,这有助于通过始终实例化视图模型来减少控制器代码,而不管数据库模型是否为null。我看到了差异(一个是对true的评估,另一个是对false的评估),但是我在这里并不完全遵循MSIL的流程(在阅读它方面相当缺乏经验)。看起来后者的计算结果又多了一行,因为有两个返回语句,但唯一的区别是007上的GOTO?
.method public hidebysig specialname rtspecialname
instance void .ctor(string param) cil managed
{
// Code size 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void AccountParserCSV.Expense::.ctor()
IL_0006: ldarg.1
IL_0007: brtrue.s IL_000a
IL_0009: ret
IL_000a: ldstr "test"
IL_000f: call void [mscorlib]System.Console::WriteLine(string)
IL_0014: ret
}