簡體   English   中英

LINQ不等於不起作用?

[英]LINQ Not Equals Not Working?

我正在嘗試解決一個問題,我需要管理一個數字范圍的數組,並且需要確保集合中的數字范圍不會相互沖突。 對於那些已經弄清楚了的人:是的,我在談論網絡,但是我正在嘗試簡化本文。 :-)

我花了一分鍾(或者可能是兩分鍾),但是我想出了以下邏輯測試:

  1. 確定現有的結尾(最后一個)是否小於新的開頭(新的第一個)。
  2. 確定現有的開頭(第一個)是否大於新的結尾(新的最后一個)。
  3. 如果#1的結果與#2的結果不同,則范圍不會沖突。

據我所知(並在Excel中復制),這是合理的邏輯。 但是,當我嘗試用C#在LINQ中編寫此邏輯並隨后在PowerShell中執行時,它不起作用。 對於冗長的PowerShell輸出,我深表歉意。

我應該如何在LINQ中編寫此邏輯? 我哪里做錯了?

C#代碼:

public class NumberRange
{
    public int First;
    public int Last;

    public NumberRange()
    {
    }

    public NumberRange(int first, int last)
    {
        First = first;
        Last = last;
    }
}

public class NumberRangeCollection : Collection<NumberRange>
{
    protected override void InsertItem(int index, NumberRange item)
    {
        NumberRange[] existingItem = this.Where(x => ((x.Last < item.First) != (x.First > item.Last))).ToArray();
        if (existingItem.Any()) throw new ArgumentException("New range collides with an existing range.", "item");

        base.InsertItem(index, item);
    }
}

PowerShell命令:

PS> $range1 = New-Object TestLibrary.NumberRange -ArgumentList @(3, 4)
PS> $range2 = New-Object TestLibrary.NumberRange -ArgumentList @(4, 5)
PS> $range3 = New-Object TestLibrary.NumberRange -ArgumentList @(5, 6)
PS> $bigrange = New-Object TestLibrary.NumberRange -ArgumentList @(3, 6)
PS> $b = New-Object TestLibrary.NumberRangeCollection
PS> $b.Add($range1)
PS> $b.Add($bigrange) # This should fail, but doesn't
PS> $b | Format-Table -AutoSize

First Last
----- ----
    3    4
    3    6


PS> $b = New-Object TestLibrary.NumberRangeCollection
PS> $b.Add($range2)
PS> $b.Add($bigrange) # This should fail, but doesn't
PS> $b | Format-Table -AutoSize

First Last
----- ----
    4    5
    3    6


PS> $b = New-Object TestLibrary.NumberRangeCollection
PS> $b.Add($range3)
PS> $b.Add($bigrange) # This should fail, but doesn't
PS> $b | Format-Table -AutoSize

First Last
----- ----
    5    6
    3    6


PS> $b = New-Object TestLibrary.NumberRangeCollection
PS> $b.Add($range4)
PS> $b.Add($bigrange) # This should fail, does, but doesn't throw the right exception.
Exception calling "Add" with "1" argument(s): "Object reference not set to an instance of an object."
At line:1 char:1
+ $b.Add($bigrange)
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : NullReferenceException

PS> $b | Format-Table -AutoSize
PS> $b = New-Object TestLibrary.NumberRangeCollection
PS> $b.Add($bigrange)
PS> $b.Add($range1) # This should fail, but doesn't
PS> $b.Add($range2) # This should fail, but doesn't
PS> $b.Add($range3) # WOOT!  The only one that works!
Exception calling "Add" with "1" argument(s): "New range collides with an existing range.
Parameter name: item"
At line:1 char:1
+ $b.Add($range3)
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException

PS> $b.Add($range4) # This should fail, does, but doesn't throw the right exception.
Exception calling "Add" with "1" argument(s): "Object reference not set to an instance of an object."
At line:1 char:1
+ $b.Add($range4)
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : NullReferenceException

PS> $b | Format-Table -AutoSize

First Last
----- ----
    3    6
    3    4
    4    5

謝謝@JonSkeet,因為我發現這樣做的第二個問題,因此建議您重寫它。

因此,我的問題的答案有兩個:

  1. LINQ邏輯很好(使用!=),但是InsertItem中的邏輯相反。 我要么需要將!=更改為==,要么將if (existingItem.Any())更改為if (!existingItem.Any()) 我選擇了前者。
  2. $ range4不存在(其他測試的剩余部分)。

這是完整的工作代碼(全部在C#中):

public class NumberRange
{
    public int First;
    public int Last;

    public NumberRange()
    {
    }

    public NumberRange(int first, int last)
    {
        First = first;
        Last = last;
    }
}

public class NumberRangeCollection : Collection<NumberRange>
{
    public NumberRange BigRange = new NumberRange(3, 6);
    public NumberRange Range1 = new NumberRange(3, 4);
    public NumberRange Range2 = new NumberRange(4, 5);
    public NumberRange Range3 = new NumberRange(5, 6);

    protected override void InsertItem(int index, NumberRange item)
    {
        NumberRange[] existingItem = this.Where(x => ((x.Last < item.First) == (x.First > item.Last))).ToArray();
        if (existingItem.Any()) throw new ArgumentException("New range collides with an existing range.", "item");

        base.InsertItem(index, item);
    }

    public NumberRangeCollection RunTest1()
    {
        Clear();
        Add(Range1);
        Add(BigRange);
        return this;
    }

    public NumberRangeCollection RunTest2()
    {
        Clear();
        Add(Range2);
        Add(BigRange);
        return this;
    }

    public NumberRangeCollection RunTest3()
    {
        Clear();
        Add(Range3);
        Add(BigRange);
        return this;
    }

    public NumberRangeCollection RunTest4()
    {
        Clear();
        Add(BigRange);
        try
        {
            Add(Range1);
        }
        catch
        {
        }
        try
        {
            Add(Range2);
        }
        catch
        {
        }
        try
        {
            Add(Range3);
        }
        catch
        {
        }
        return this;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM