我可以在方法调用中强制自己的短路吗?

Dan*_*Tao 5 .net c# short-circuiting

假设我想检查一堆对象以确保none为null:

if (obj != null &&
    obj.Parameters != null &&
    obj.Parameters.UserSettings != null) {

    // do something with obj.Parameters.UserSettings
}
Run Code Online (Sandbox Code Playgroud)

编写一个辅助函数来接受可变数量的参数并简化这种检查是一个诱人的前景:

static bool NoNulls(params object[] objects) {
    for (int i = 0; i < objects.Length; i++)
        if (objects[i] == null) return false;

    return true;
}
Run Code Online (Sandbox Code Playgroud)

然后上面的代码可能变成:

if (NoNulls(obj, obj.Parameters, obj.Parameters.UserSettings)) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

对?错误.如果obj是空的话,我会得到一个NullReferenceException,当我试图通过obj.ParametersNoNulls.

所以上述方法显然是错误的.但是if使用&&运算符的声明工作得很好,因为它是短路的.那么:有没有办法让方法短路,以便在方法中明确引用之前不会对其参数进行求值?

Jon*_*eet 9

嗯,这很丑,但......

static bool NoNulls(params Func<object>[] funcs) {
    for (int i = 0; i < funcs.Length; i++)
        if (funcs[i]() == null) return false;

    return true;
}
Run Code Online (Sandbox Code Playgroud)

然后用:

if (NoNulls(() => obj,
            () => obj.Parameters,
            () => obj.Parameters.UserSettings)) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

基本上,您提供委托来懒惰地评估值,而不是值本身(因为评估这些值是导致异常的原因).

我不是说它很好,但它可以作为一种选择......

编辑:我认为这实际上(并且意外地)触及了Dan所追求的核心.在执行方法本身之前,会对所有方法的参数进行求值.有效地使用委托可以让您延迟评估,直到方法需要调用委托来检索值.

  • 它是丑陋和令人困惑的,但是没有空合并操作符可以做到这一点:`if((object z = a ?? b ?? c)!= null)DoSomething();` (4认同)