当前位置:  开发笔记 > 编程语言 > 正文

如何在C#<6中模拟C#6空条件

如何解决《如何在C#<6中模拟C#6空条件》经验,为你挑选了2个好方法。

使用C#6.0,我可以做到这一点

var isEqual = x.Id == y.Id
              && x.UpdatedAt == y.UpdatedAt
              && x.Name == y.Name                        
              && x.RulesUrl == y.RulesUrl
              && x.OngoingChallenges?.Count == y.OngoingChallenges?.Count
              && x.MembershipIds?.Count == y.MembershipIds?.Count;

C#<6.0有没有很好的解决方案呢?

我的意思是这部分

&& x.OngoingChallenges?.Count == y.OngoingChallenges?.Count
&& x.MembershipIds?.Count == y.MembershipIds?.Count;

因为在旧项目中我们没有可能使用C#6.0.怎么写得isEqual高效?



1> Olivier Jaco..:

在C#version <6.0中,您将使用三元表达式

var isEqual = x.Id == y.Id
    && x.UpdatedAt == y.UpdatedAt
    && x.Name == y.Name                        
    && x.RulesUrl == y.RulesUrl
    && (x.OngoingChallenges == null ? 0 : x.OngoingChallenges.Count) ==
       (y.OngoingChallenges == null ? 0 : y.OngoingChallenges.Count)
    && (x.MembershipIds == null : 0 ? x.MembershipIds.Count) == 
       (y.MembershipIds == null : 0 : y.MembershipIds.Count);

正如@Hamlet Hakobyan指出的那样,这不是原始C#6.0解决方案的语义完全等同?.,但您可以将其更改为(根据@hvd):

int? count = x.MembershipIds == null : default(int?) ? x.MembershipIds.Count;

这取决于您是否要考虑缺少集合和空集合是否相等.


您还可以使用null-coalescing运算符??并提供替换对象.假设您的对象是某种类型的列表:

var empty = new List();
var isEqual = x.Id == y.Id
    && x.UpdatedAt == y.UpdatedAt
    && x.Name == y.Name                        
    && x.RulesUrl == y.RulesUrl
    && (x.OngoingChallenges ?? empty).Count == (y.OngoingChallenges ?? empty).Count
    && (x.MembershipIds ?? empty).Count == (y.MembershipIds ?? empty).Count;


你的第一个解决方案有问题 它假设`null等于0`这是错误的假设.

2> Matías Fidem..:

x.OnGoingChallenges?.Count相当于x.OnGoingChallenges != null ? x.OnGoingChallenges.Count : default(int?)(还有其他方法,但在一天结束时是一个称为空条件运算符的空检查的快捷方式).

也就是说,在没有C#6的情况下,您的代码不能用合成优雅的语句重写,但您可以使用扩展方法模拟这个新的C#6功能...

public static class StructExtensions
{
    // Check that TProperty is nullable for the return value (this is how C#6's
    // null-conditional operator works with value types
    public static TProperty? GetOrDefault(this TObject someObject, Func propertySelectionFunc)
        where TObject : class 
        where TProperty : struct
    {
        Contract.Requires(propertySelectionFunc != null);

        return someObject == null ? default(TProperty?) : propertySelectionFunc(someObject);
    }
}

现在,您在C#5中的代码如下所示:

var isEqual = x.Id == y.Id
                          && x.UpdatedAt == y.UpdatedAt
                          && x.Name == y.Name                        
                          && x.RulesUrl == y.RulesUrl
                          && x.OngoingChallenges.GetOrDefault(c => c.Count) == y.OngoingChallenges.GetOrDefault(c => c.Count)
                          && x.MembershipIds.GetOrDefault(m => m.Count) == x.MembershipIds.GetOrDefault(m => m.Count);

整个扩展方法可用于获取值类型属性值或其默认值.您可能会也可能不会扩展扩展方法类,以支持获取引用类型值或null.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有