C #: تقاطع المدى عندما تكون نقاط النهاية فارغة (اللانهاية)

StackOverflow https://stackoverflow.com/questions/1729370

سؤال

حسنا، لدي هذه الأساليب التقاطع للعمل مع النطاقات، وأنها تعمل بشكل جيد طالما أن نقاط النهاية النطاق ليست فارغة:

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

مشكلتي الآن هو أنني أود منهم أن يدعموا بالضبط، ونقاط النهاية الفارغة. سوف نقطة نهاية فارغة أن النطاق يذهب إلى ما لا نهاية في هذا الاتجاه. اثنين من الاختبارات التي أود تمريرها، وهذا لا، هو على سبيل المثال هذه:

[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 أولا وفعل شيء خاص أو لجعل نوعا من IComparer<T> غلاف ... لكنني غير قادر على معرفة أي وكيف يجب عليهم العمل. يجب أن نتذكر أنه يمكن أن يعطى أي نوع من المقارنة أيضا، لذلك يمكن أن تكون النطاقات من الناحية الفنية في الاتجاه المعاكس، طالما أن المقارنة المعطاة يأخذ ذلك في الاعتبار بالطبع (في القانون الحقيقي الذي ألقي استثناء إذا جاءت البداية بعد النهاية وفقا للمقارنة المعينة). على أي حال، أنا ضائع قليلا هنا: ص

هل كانت مفيدة؟

المحلول

أعتقد أنك بحاجة إلى مراعاة nulls في المقارنة.

هل هذا لا يساعد؟

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

حسنا، للجزء الثاني. قم بتعيين البدء والنهاية إلى NULL، ويتم تعيينه فقط على القيم البدء / الإنهاء إذا لم يكن كلاهما فارغا.

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);
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top