C #: Gamma di intersezione quando gli endpoint sono nulli (infinito)
-
19-09-2019 - |
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
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);
}