*** 作方法:在例如实现的短路反向三元运算符中实现. C#?有关系吗?

 *** 作方法:在例如实现的短路反向三元运算符中实现. C#?有关系吗?,第1张

概述假设您正在使用三元运算符或空合并运算符或嵌套的if-else语句来选择对象的赋值.现在假设在条件语句中,您对昂贵或易失性 *** 作进行了评估,要求将结果放入临时变量中,捕获其状态,以便可以对其进行比较,然后进行可能的分配. 一个语言(如C#)如何实现一个新的逻辑运算符来处理这种情况?应该是?在C#中是否存在处理此案例的现有方法?其他语言? 例如,当我们假设我们正在寻找直接比较时,已经克服了一些降低三元或 假设您正在使用三元运算符或空合并运算符或嵌套的if-else语句来选择对象的赋值.现在假设在条件语句中,您对昂贵或易失性 *** 作进行了评估,要求将结果放入临时变量中,捕获其状态,以便可以对其进行比较,然后进行可能的分配.

一个语言(如C#)如何实现一个新的逻辑运算符来处理这种情况?应该是?在C#中是否存在处理此案例的现有方法?其他语言?

例如,当我们假设我们正在寻找直接比较时,已经克服了一些降低三元或零合并运算符的冗长度的情况.请参阅Unique ways to use the Null Coalescing operator,特别是关于如何扩展运算符的使用以支持String.IsNullOrEmpty(string)的讨论.注意Jon Skeet如何使用MiscUtil中的PartialComparer将0重新格式化为空值,

为什么这可能是必要的?那么,看看我们如何为没有任何快捷方式的复杂对象编写比较方法(引用的讨论中的示例):

public static int Compare( Person p1,Person p2 ){    return ( (result = Compare( p1.Age,p2.Age )) != 0 ) ? result        : ( (result = Compare( p1.name,p2.name )) != 0 ) ? result        : Compare( p1.Salary,p2.Salary );}

Jon Skeet写了一个新的比较来回避平等案例.这允许通过编写一个返回null的新特定方法来扩展表达式,允许我们使用null合并运算符:

return PartialComparer.Compare(p1.Age,p2.Age)    ?? PartialComparer.Compare(p1.name,p2.name)    ?? PartialComparer.Compare(p1.Salary,p2.Salary)    ?? 0;

空合并运算符更具可读性,因为它有两个边,而不是三个边. boolean condition子句被分隔为一个方法,在这种情况下,如果必须继续表达式,则返回null.

如果我们可以更容易地将条件置于线上,那么上面的表达式会是什么样的?从PartialComparer.Compare中获取返回null的表达式,并将其放在一个新的三元表达式中,该表达式允许我们使用左侧表达式的求值,并使用隐式临时变量值:

return Compare( p1.Age,p2.Age ) unless value == 0     : Compare( p1.name,p2.name ) unless value == 0     : Compare( p1.Salary,p2.Salary );

表达式的基本“流程”将是:

Expression A unless boolean B in which case Expression C

我认为这更像是一个短路的倒三元运算符,而不是一个重载的比较运算符.

>这种逻辑会有用吗?目前,null合并为我们提供了一种使用条件表达式(value == null)执行此 *** 作的方法.
>您想要测试哪些其他表达方式?我们听说过(String.IsNullOrEmpty(value)).
>在 *** 作符,关键字方面,用语言表达这一点的最佳方式是什么?

解决方法 我个人避免运算符的短路,只是让方法链接它:

public static int CompareChain<T>(this int prevIoUs,T a,T b){    if (prevIoUs != 0)        return prevIoUs;    return Comparer<T>.Default.Compare(a,b);}

像这样使用:

int a = 0,b = 2;string x = "foo",y = "bar";return a.Compare(b).CompareChain(x,y);

可以通过JIT内联,因此它可以像语言中内置的短路一样执行,而不会产生更多的复杂性.

在回答您询问上述“结构”是否可以应用于不仅仅是比较时,可以通过选择是否继续或不可由用户进行控制来实现.这本质上更复杂,但 *** 作更灵活,因此这是不可避免的.

public static T ElseIf<T>(    this T prevIoUs,Func<T,bool> isOK    Func<T> candIDate){    if (prevIoUs != null && isOK(prevIoUs))        return prevIoUs;    return candIDate();}

然后像这样使用

Connection bestConnection = server1.GetConnection()    .ElseIf(IsOk,server2.GetConnection)    .ElseIf(IsOk,server3.GetConnection)    .ElseIf(IsOk,() => null);

这是最大的灵活性,因为您可以在任何阶段更改IsOk检查并且完全是懒惰的.对于OK检查在每种情况下都是相同的情况,您可以像这样简化并完全避免扩展方法.

public static T ElseIf<T>(            Func<T,bool> isOK    IEnumerable<Func<T>[] candIDates){   foreach (var candIDate in candIDates)   {         var t = candIDate();        if (isOK(t))            return t;   }   throw new ArgumentException("none were acceptable");}

您可以使用linq执行此 *** 作,但这样可以提供一个很好的错误消息并允许此 *** 作

public static T ElseIf<T>(            Func<T,bool> isOK    params Func<T>[] candIDates){    return ElseIf<T>(isOK,(IEnumerable<Func<T>>)candIDates);}

样式导致可读的代码如下:

var bestConnection = ElseIf(IsOk,server1.GetConnection,server2.GetConnection,server3.GetConnection);

如果要允许默认值,则:

public static T ElseIfOrDefault<T>(            Func<T,bool> isOK    IEnumerable<Func<T>>[] candIDates){   foreach (var candIDate in candIDates)   {         var t = candIDate();        if (isOK(t))            return t;   }   return default(T);}

显然,以上所有内容都可以使用lambdas编写,因此您的具体示例如下:

var bestConnection = ElseIfOrDefault(    c => c != null && !(c.IsBusy || c.IsFull),server3.GetConnection);
总结

以上是内存溢出为你收集整理的 *** 作方法:在例如实现的短路反向三元运算符中实现. C#?有关系吗?全部内容,希望文章能够帮你解决 *** 作方法:在例如实现的短路反向三元运算符中实现. C#?有关系吗?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1215498.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存