Domanda

Ok, ho questi metodi intersezione per lavorare con intervalli, e funzionano bene finché gli endpoint gamma non sono nulli:

public static bool Intersects<T>(this Range<T> first, Range<T> second, IComparer<T> comparer)
{
    return comparer.Compare(first.Start, second.End) <= 0 
        && comparer.Compare(first.End, second.Start) >= 0;
}

public static Range<T> GetIntersectionWith<T>(this Range<T> first, Range<T> second,
    IComparer<T> comparer)
{
    // Return null, if any range is null or if they don't  intersect at all
    if (first == null || second == null || !Intersects(first, second, comparer))
        return null;

    var start = comparer.Compare(first.Start, second.Start) < 0 
                    ? second.Start 
                    : first.Start;
    var end = comparer.Compare(first.End, second.End) > 0 
                    ? second.End 
                    : first.End;

    return Range.Create(start, end);
}

Il mio problema ora è che mi piacerebbe loro di sostenere esattamente questo, gli endpoint nulli. Un endpoint nullo significherebbe che la gamma va all'infinito in quella direzione. Due test che vorrei passare, che non lo fa, sono ad esempio questi:

[Test]
public void Intersects_Intersecting_OneEndsWithNull()
{
    var a = Range.Create("a", "k");
    var b = Range.Create("c", null);

    Assert.That(a.Intersects(b), Is.True);
    Assert.That(b.Intersects(a), Is.True);
}

[Test]
public void GetIntersectionWith_Intersecting_OneStartingAndOneEndingWithNull()
{
    var a = Range.Create(null, "k");
    var b = Range.Create("f", null);
    var expected = Range.Create("f", "k");

    Assert.That(a.GetIntersectionWith(b), Is.EqualTo(expected));
    Assert.That(b.GetIntersectionWith(a), Is.EqualTo(expected));
}

Il motivo per cui non funziona subito è che nulla è considerato meno di tutto. Ma qui nulla hanno da qualche volta considerato maggiore di tutto.

Qualsiasi idea di come questo possa essere risolto in senso buono?

Sto pensando io sia deve controllare da null prima e fare qualcosa di speciale o per fare una sorta di involucro IComparer<T> ... ma io non sono in grado di capire quale o come avrebbero dovuto lavorare. Devo ricordare che potrebbe essere dato alcun tipo di operatore di confronto anche, in modo tecnicamente i campi potrebbero essere nella direzione opposta, fino a quando il dato di confronto tiene conto di questo, naturalmente, (Nel codice vero e proprio ho un'eccezione se la partenza viene dopo la fine secondo il dato di confronto). In ogni modo, io sono un po 'perso qui: P

È stato utile?

Soluzione

Credo che è necessario prendere in considerazione i valori nulli nel confronto.

sarebbe questo non aiuta?

public static bool Intersects<T>(this Range<T> first, Range<T> second, IComparer<T> comparer)
        {    
            return (ReferenceEquals(first.Start, null) || ReferenceEquals(second.End, null) || comparer.Compare(first.Start, second.End) <= 0)
                && (ReferenceEquals(first.End, null) || ReferenceEquals(second.Start, null) || comparer.Compare(first.End, second.Start) >= 0);
        }

OK, per la seconda parte. impostare inizio e fine per nulla, e solo impostare per avviare / valori estremi se entrambi non è nullo.

public static Range<T> GetIntersectionWith<T>(this Range<T> first, Range<T> second, IComparer<T> comparer)
    {
        // Return null, if any range is null or if they don't  intersect at all
        if (first == null || second == null || !Intersects(first, second, comparer))
            return null;

        T start;
        if (ReferenceEquals(first.Start, null))
            start = second.Start;
        else if (ReferenceEquals(second.Start, null))
            start = first.Start;
        else
            start = comparer.Compare(first.Start, second.Start) < 0 
                        ? second.Start 
                        : first.Start;        
        T end;
        if (ReferenceEquals(first.End, null))
            end = second.End;
        else if (ReferenceEquals(second.End, null))
            end = first.End;
        else
            end = comparer.Compare(first.End, second.End) > 0 
                        ? second.End 
                        : first.End;

        return Range.Create(start, end);
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top