一个语言(如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#?有关系吗?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)