C#:端点为空(无穷大)时的范围交集

好的,我有这些交集方法来处理范围,只要范围端点不为null,它们就可以正常工作:

public static bool Intersects(this Range first, Range second, IComparer comparer) { return comparer.Compare(first.Start, second.End) = 0; } public static Range GetIntersectionWith(this Range first, Range second, IComparer 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.End : first.End; return Range.Create(start, end); } 

我现在的问题是,我希望他们能够完全支持null端点。 空终点意味着该范围在该方向上变为无穷大。 我希望传递的两个测试,例如:

 [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)); } 

它不能立即工作的原因是null被认为少于一切。 但是这里的null必须被认为比一切都要

知道如何以一种好的方式解决这个问题吗?

我想我要先检查是否为null并做一些特殊的事情或制作某种IComparer包装器…但我无法弄清楚它们必须工作的方式或方式。 必须记住它也可以给出任何类型的比较器,所以从技术上来说,范围可能是相反的方向,只要给定的比较器当然考虑到这一点(在实际代码中,如果开始时我会抛出exception)根据给定的比较器结束后)。 无论如何,我在这里有点迷失:P

我认为你需要考虑比较中的空值。

这不会有帮助吗?

 public static bool Intersects(this Range first, Range second, IComparer 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); } 

好的,第二部分。 将start和end设置为null,并且仅当两者都不为null时才设置为start / end值。

 public static Range GetIntersectionWith(this Range first, Range second, IComparer 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); }