2

a ?? b

  • 如果a不是null=> 则返回a
  • 否则(anull)=> 返回b

我想模拟类似它的逆的东西(AFAIK 没有运营商可以做到这一点):

  • 如果anull=> 返回a
  • 否则(a不是null)=> 返回b

这个想法是,这b将是一个接收a并需要避免null参数的函数的结果。像这样:a XX fn(a)其中 XX 将是运算符(如果存在)。

我仅有的两个变体是:

  • a == null ? a : fn(a)
  • a == null ? null : fn(a)

有没有办法简化这段代码?

4

5 回答 5

3

不确定您要完成什么?像这样的东西?

TResult NullFn<TParam, TResult>(TParam a, Func<TParam, TResult> method)
{
if(a == null) return null;
return method(a);
}

...

var result = NullFn(a, a => fn(a))

但是最好的解决方案恕我直言,fn如果它传递了一个空值,则只返回空值。

编辑:

顶部的方法只是一个示例。您可能希望在特定区域一遍又一遍地进行大量相同操作并且您无法更改 fn 的情况下使用类似的东西,因为它会使您更容易专注于其余部分代码,并且您可能希望在将来一次更改所有操作的空处理行为。(我假设是这种情况,因为您首先要问。)但是我不会在整个应用程序中使用它,因为如果您没有NullFn前面的功能,不清楚会发生什么你的。

于 2012-12-13T20:43:20.603 回答
1

简单条件有什么问题?

if (a != null) b = fn(a);

另一种选择 - 为您的方法添加条件:

public B fn(A a)
{
    if (a == null)
        return null;

    return new B();
}
于 2012-12-13T20:38:18.543 回答
1

我个人更喜欢

(a != null) ? fn(a) : null

因为我认为它使意图更加明显,但我想不出一种方法来简化那么多。如果您愿意,可以使用扩展方法。

a.CallIfNotNull(fn)

使用以下扩展方法

internal static T CallIfNotNull<T>(this T value, Func<T, T> function)
    where T : class
{
    return (value != null) ? function(value) : null;
}

不是真的更好,但可能更不容易出错并且更容易输入 IntelliSense。

(假设函数返回的值与问题所暗示的参数类型相同。)

于 2012-12-13T20:47:15.643 回答
0

如果您拥有T a;T fn(T a);使用相同的用户定义类型 T,那么您可以编写a && fn(a)并将其扩展为T.False(a) ? a : T.&(a, fn(a)).

于 2012-12-13T20:45:07.957 回答
0

您已经用底部的 ?: 实现回答了您自己的问题。

我建议的唯一改进是将功能包装在一种方法中,使其更清洁且不易出错。

object SafeB(object a)
{
    return a==null ? a : b(a);
}

编译器可能会内联它,这样你就不会失去性能。

您甚至可以将其实现为提供 b 的类的扩展方法,从而使其成为更加集成的解决方案。

于 2012-12-13T20:52:55.463 回答