空参数替代 C# 6.0

8

我看到了 C# 6 的新功能,允许代码跳过 null 检查的 if 语句。

例如:

return p?.ToString();

如何在不使用旧的if/else语句的情况下调用需要传递参数p的方法?针对这种情况,我通常会按照以下的C# pre-6写法:
 p != null ? callmethod(p) : null

C# 6有更好的东西吗?


6
一定没有什么需要注意的"OrEmpty`部分。 - Sergey Kalinichenko
抱歉伙计,对于方法调用,你仍然要按照旧的方式来做。 - Joe_DM
3
最佳的选择是 callmethod(p ?? string.Empty)。 对于“最佳”的定义有一定限制。 - ClickRick
3
我倾向于同意,但OP想找一种方法,如果参数为null就永远不调用该方法。这样的功能并不存在。 - Joe_DM
callMethod 的使用者不应该关心/知道方法具有哪些验证规则 - 他们只需传递满足方法契约/签名的参数即可。如果您从其他地方获取 p 并希望在进一步传递之前进行验证 - 为了可读性,最好像以前那样显示您的意图进行验证。 - Fabio
显示剩余2条评论
4个回答

8
你可以使用一个扩展方法——你可以将其泛化到任何情况。这是可行的,因为C#允许扩展方法与null值一起使用this参数(令人惊讶!),而对于普通实例方法,否则你会得到NullReferenceException
以下是类似于我在自己的项目中使用的内容,在C# 6之前我们拥有?.“安全导航”运算符:
public static class Extensions
{    
    public static TRet NullSafeCall<TValue,TRet>( this TValue value, Func<TValue,TRet> func )
        where TValue : class
        where TRet : class
    {
        if( value != null ) return func( value );
        return null;
    }
}

使用方法如下:

return p.NullSafeCall( callmethod );

如果您需要将多个参数传递到后续的func中,则可以使用lambda表达式来实现:

String foo = "bar";
return p.NullSafeCall( v => callmethod2( v, foo ) );

在您的示例中,您使用了String.IsNullOrEmpty而不是!= null,可以像这样添加:

public static class Extensions
{    
    public static TRet NullSafeCall<TValue,TRet>( this TValue value, Func<TValue,Boolean> guard, Func<TValue,TRet> func )
        where TValue : class
        where TRet : class
    {
        if( guard( value ) ) return func( value );
        return null;
    }
}

使用方法:

return p.NullSafeCall( v => String.IsNullOrEmpty( v ), v => callmethod( v ) );

当然,你可以将它串联起来:
return p
    .NullSafeCall( callmethod2 )
    .NullSafeCall( callmethod3 )
    .NullSafeCall( v => callmethod4( v, "foo", bar ) );

2
关于Null-conditional运算符的内容可以在这里阅读。
对于参数的null检查,替代方案是使用??运算符,用法如下:
someMethod(val??"0");// this means that "0" will be passed as a value if val is null

但这与检查空字符串无关。因此,如果不允许value为空,则仍需要检查空字符串。

2
据我所知,使用if语句是很好的选择,因为它能够清晰地表达你的意图。另一种缓解这个问题的方法是在字符串“callmethod”上创建一个扩展方法。
public static class extension
{
     public static void callmethod (this string myInput)
     {}
}

因此,您将能够实现

p?.callmethod();

0

没有使用'if else',你可以通过以下代码实现-

p!=string.Empty?callmethod(p):"";

这行代码是无效的,没有任何运算符来检查它的结果。即使加上运算符,它只是调用 callmethod(p) 并检查 p 是否等于 callmethod(p) 返回的结果。 - Samvel Petrosov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接