完成层次较高的函数

本文关键字:函数 层次 | 更新日期: 2023-09-27 18:03:03

我写累了:

if(objectA!=null) 
return;

或:

if(objectB==null) 
return;

所以我希望把这个片段缩短成这样:

Returns.IfNull(objectA);

非常匹配相同的长度,但通常要检查的对象很少,添加params作为参数可以缩短:

if(objectA==null || objectB!=null || objectC!=null) 
return;

:

Returns.IfNull(objectA,objectB,objectC);

基本上,函数IfNull必须访问堆栈跟踪中更高一步的函数并完成它。但这只是一个想法,我不知道这是否可能。我能在一些库中找到类似的逻辑吗?

完成层次较高的函数

不,你实际上是在要求函数退出高于自身的函数,这是不可取的,也不可能的,除非你抛出一个异常(它本身不返回)。

因此,您可以执行简单而简洁的if-null-return检查,或者您可能想要做的是抛出一个定义良好的异常,但我不建议对流控制使用异常。但是,如果这些是异常(错误)情况,则考虑抛出ArgumentNullException()并酌情处理。

您可以编写一些帮助器方法来为您抛出ArgumentNullException(),当然,可以稍微清理一下:

    public static class ArgumentHelper
    {
        public static void VerifyNotNull(object theObject)
        {
            if (theObject == null)
            {
                throw new ArgumentNullException();
            }
        }
        public static void VerifyNotNull(params object[] theObjects)
        {
            if (theObjects.Any(o => o == null))
            {
                throw new ArgumentNullException();
            }
        }
    }

那么你可以写:

public void SomeMethod(object obj1, object obj2, object obj3)
{
    ArgumentHelper.VerifyNotNull(obj1, obj2, obj3);
    // if we get here we are good!
}

但是,这是异常,而不是堆栈中前一个方法的"返回",这是不可能的。

你要求的东西只有语言设计者才能为你解决。我自己提出了一件事。的。?当留给操作符的参数为空时,操作符从当前方法返回默认返回值。

return appSettings.?GetElementKey(key).?Value ?? "";
也许有一天我们会在c# 6中看到它?

为了进行类似的比较检查,我曾经定义了以下扩展方法:

/// <summary>
///   Returns whether the object equals any of the given values.
/// </summary>
/// <param name = "source">The source for this extension method.</param>
/// <param name = "toCompare">The objects to compare with.</param>
/// <returns>
///   True when the object equals any of the passed objects, false otherwise.
/// </returns>
public static bool EqualsAny( this object source, params object[] toCompare )
{
    return toCompare.Any( o => o.Equals( source ) );
}

可以简化冗余检查,例如:

string someString = "bleh";
bool anyEquals = someString.EqualsAny( "bleh", "bloeh" );

在您检查多个空检查的情况下,您可以使用它如下:

if ( EqualsAny( null, objectA, objectB, objectX ) ) return;

另一方面,你的代码让我想起了代码契约,它允许你定义前置和后置条件。如果这是你的场景-也许不是,因为我不明白为什么你叫return -它可能会让你感兴趣。部分功能在。net 4.0中可以免费获得。

你不能调用另一个方法,并期望它返回到当前方法的被调用者(如果我们有延续传递风格;唉,我们没有)。

你可以说:

if(new[] { objectA, objectB, objectC }.Any(x => x != null)) {
    return;
}

或:

if(new[] { objectA, objectB, objectC }.AnyAreNotNull()) {
    return;
}

这里,AnyAreNotNull为:

public static class EnumerableExtensions {
    public static bool AnyAreNotNull<T>(this IEnumerable<T> source) {
        Contract.Requires(source != null);
        return source.Any(x => x != null);
    }
}

但实际上,对于这种情况,只编写通常的代码并没有什么错。

不能,一个方法不能返回它上面的方法。

你能做的最好的是创建一个方法,返回true,如果它的任何参数是空的,然后做if (ReturnHelper.AllNull(obj1, obj2, obj3)) return;,但我想说这是可读性差得多。