C# “模拟类运算符”;“的反比”;

C# “模拟类运算符”;“的反比”;,c#,operators,C#,Operators,a??b 如果a不是null=>则返回a Else(a为null)=>返回b 我想模拟它的倒数形式(假设没有操作符): 如果a为null=>返回a Else(a不是null)=>返回b 其思想是,b将是接收a的函数的结果,并且需要避免null参数。这样:a XX fn(a)其中XX将是操作符(如果存在) 我唯一的两个变体是: a==null?答:fn(a) a==null?空:fn(a) 有没有办法简化这个代码?简单条件有什么问题 if (a != null) b = fn(a);

a??b

  • 如果
    a
    不是
    null
    =>则返回
    a
  • Else(
    a
    null
    )=>返回
    b
我想模拟它的倒数形式(假设没有操作符):

  • 如果
    a
    null
    =>返回
    a
  • Else(
    a
    不是
    null
    )=>返回
    b
其思想是,
b
将是接收
a
的函数的结果,并且需要避免
null
参数。这样:
a XX fn(a)
其中XX将是操作符(如果存在)

我唯一的两个变体是:

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

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

简单条件有什么问题

if (a != null) b = fn(a);
另一个选项-向方法中添加条件:

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

    return new B();
}

不确定你到底想完成什么?像这样的

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))
TResult NullFn(TParam a,Func方法)
{
如果(a==null)返回null;
返回方法(a);
}
...
var结果=NullFn(a,a=>fn(a))
但最好的解决方案是,如果传递空值,则让
fn
返回null

编辑:


顶部的方法只是一个示例。您可能希望在这样的情况下使用这样的方法,即在特定区域反复执行许多相同的操作,并且您无法更改fn,因为这样可以更容易地关注代码的其余部分,并且将来您可能希望同时更改所有操作的空处理行为。(我假设是这样的,因为您首先会问。)但我不会在整个应用程序中使用它,因为不清楚如果您前面没有
NullFn
函数会发生什么
tfn(ta)
使用相同的用户定义类型T,然后您可以编写
a&&fn(a)
,它将扩展到
T.False(a)?a:T.&(a,fn(a))
我个人更喜欢

(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;
}
内部静态T CallIfNotNull(此T值,Func函数)
T:在哪里上课
{
返回(值!=null)?函数(值):null;
}
虽然不是很好,但在给定IntelliSense的情况下,可能不太容易出错,也更容易键入


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

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

我建议的唯一改进是将功能包装在一个方法中,使其更干净,更不容易出错

object SafeB(object a)
{
    return a==null ? a : b(a);
}
编译器可能会将其内联,这样您就不会失去性能


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

让方法fn检查参数是否为null不是更容易吗?fn(a)的类型是什么?您不能向该语言添加新的运算符,那么重点是什么呢?你的两条线很简单。为什么你认为你需要比你现有的更简单的东西?你是否经常这样做,以至于你认为有一个接线员来做这件事真的值得?如果你真的这么做的话,你可以制作一个方法来实现这一点。@Neil类型会改变什么吗?你可能也可以将
对象
设置为泛型类型。代码只是一个我不建议实际使用的示例。我建议的真正解决方案是将条件添加到方法
fn
。添加NullFn方法对将来出现的任何人来说都会非常混乱。没错,这只是一个一般性的注释:)我无论如何都要添加它,我在编写方法时认为,将结果类型设置为泛型将防止从用法中推断类型,而无需每次都显式地编写它,但事实并非如此。从名称来看,我更希望它是
fn.CallIfNotNull(a)
。我也考虑过这一点,但不确定是否可以轻松调用方法组上的扩展方法-我不这么认为-或者是否必须首先将该方法分配给委托类型变量,从而使调用站点非常难看。这是一个非常聪明的主意…但不幸的是,会产生隐藏的代码。@DanielBrückner,也许对Python、JavaScript、Perl等的用户来说不那么神秘?