完成层次结构更高的功能

时间:2011-07-19 20:45:39

标签: c#

我厌倦了写作:

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必须在堆栈跟踪中获得更高一级的功能并完成它。但那是唯一的想法,我不知道它是否可能。我可以在某些lib中找到相似的逻辑吗?

5 个答案:

答案 0 :(得分:7)

不,你基本上要求函数退出比自身更高的函数,这是不可取的,也不是真的可能,除非你抛出一个异常(它本身没有返回)。

因此,您可以执行简单明了的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!
}

但是再一次,这是异常而不是堆栈中前一个方法的“返回”,这是不可能直接实现的。

答案 1 :(得分:1)

您要求只有语言设计师可以为您修复的内容。 我在myself提出了一件事。 。?当剩下的参数为null时,operator会使用默认返回值从当前方法返回。

return appSettings.?GetElementKey(key).?Value ?? "";

也许我们有一天会在C#6中看到它?

答案 2 :(得分:1)

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

/// <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;

另一方面,您的代码让我想起Code Contracts,它允许您定义前置条件和后置条件。如果这是您的情况 - 也许不是因为我不明白您为什么致电return - 它可能会让您感兴趣。部分内容在.NET 4.0中免费提供。

答案 3 :(得分: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);
    }
}

但实际上,为这种情况编写通常的代码并没有错。

答案 4 :(得分:0)

不,方法无法返回上面的方法。

你能做的最好的事情是创建一个方法,如果它的任何params为null,则返回true,然后执行if (ReturnHelper.AllNull(obj1, obj2, obj3)) return;,但我会说这个可读性要低得多。