C# 用LINQ替换阵列元素的CompareTo

C# 用LINQ替换阵列元素的CompareTo,c#,linq,for-loop,C#,Linq,For Loop,我正在做一个项目,它用柱子来代表栅栏。每个围栏正好有两个实现IComparable的立柱,并在每个围栏中进行排序。为了覆盖围栏上的CompareTo,我需要将此围栏和其他围栏之间的0柱进行比较;如果该结果返回0,那么我需要将此栏位1与另一栏位1进行比较。我编写了一个简单的for循环来执行这个逻辑,我在下面介绍了它。然而,Resharper警告我应该用LINQ替换for循环。有没有一种简单的方法可以用LINQ替换for循环 public int CompareTo(Fence other) {

我正在做一个项目,它用柱子来代表栅栏。每个围栏正好有两个实现IComparable的立柱,并在每个围栏中进行排序。为了覆盖围栏上的CompareTo,我需要将此围栏和其他围栏之间的0柱进行比较;如果该结果返回0,那么我需要将此栏位1与另一栏位1进行比较。我编写了一个简单的for循环来执行这个逻辑,我在下面介绍了它。然而,Resharper警告我应该用LINQ替换for循环。有没有一种简单的方法可以用LINQ替换for循环

public int CompareTo(Fence other)
{
    for(int i = 0; i < Posts.Length; i++)
    {
        int c = Posts[i].CompareTo(other.Posts[i]);
        if (c != 0)
            return c;
    }
    return 0;
}
public int CompareTo(围栏其他)
{
for(int i=0;i
如果ReSharper建议,您可以轻松点击AltEnterEnter,看看会发生什么。我猜是这样的:

public int CompareTo(Fence other)
{
    return Posts.Select((p, i) => p.CompareTo(other.Posts[i]))
                .FirstOrDefault(c => c != 0);
}
这会将每个
Post
的比较结果投影到
其他
围栏的相应
Post
p
Post
循环变量,
i
是索引)
FirstOrDefault
查找第一个非零比较结果,或者如果所有结果都是
0
,则返回
0

因此,这正是您的循环所做的(请注意,LINQ使用延迟执行,因此当发生第一次非零比较时,不会再比较
Post
s)


请注意,正如juharr评论的那样,此代码容易出错:您应该首先检查null
other
,并检查两个
Post
数组是否具有相同的长度。
(我猜
Posts
不是空的,并且数组不包含
null
元素,这应该由类的实现来确保)。

由于围栏正好有两个post,那么这可以减少为:

public int CompareTo(Fence other)
{
    int c = Post[0].CompareTo(other.Post[0]);
    if (c == 0)
         c = Post[1].CompareTo(other.Post[1]);
    return c;
}
请注意,您可以(也可能应该)将
Post
数组替换为
Post0
和'Post1'

请注意,这可能会给您提供与以下完全不同的订购:

    int c = Post[1].CompareTo(other.Post[1]);
    if (c == 0)
         c = Post[0].CompareTo(other.Post[0]);

据推测,这也同样有效。(也就是说,如果这个帖子[0]比另一个帖子小,但它的帖子[1]比另一个帖子大,那么围栏是比另一个帖子大还是小?

如果resharper建议这样做,为什么不点击Alt+Enter,看看会发生什么?这不是警告,只是建议。也许这只是一个提示?在某些情况下,Resharper可以将非LINQ代码块转换为LINQ代码块,反之亦然。如果
other
的帖子较少,您不应该进行长度检查吗?@dwelknarr如果只有两篇帖子,为什么还要用数组,只要有
Post1
Post2
属性就行了。我删除了我帖子中的空检查以简化它。Fence中的Posts属性是不可变的,构造函数强制执行正好有两个非null、非相等的Post对象。