Question

Ok, j'ai ces méthodes d'intersection pour travailler avec des gammes, et ils fonctionnent bien aussi longtemps que les points d'extrémité de gamme ne sont pas nulles:

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

Mon problème est maintenant que je les voudrais soutenir exactement que, paramètres nuls. Un point de terminaison nulle signifierait que la gamme tend vers l'infini dans cette direction. Deux tests que je voudrais passer, qui ne constitue pas, sont par exemple ceux-ci:

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

La raison pour laquelle il ne fonctionne pas est tout de suite que nul est considéré comme moins que tout. Mais ici nulle ont à parfois considéré comme plus que tout.

Toute idée de comment cela peut être résolu dans une bonne façon?

Je pense que je vais soit devoir vérifier null d'abord et faire quelque chose de spécial ou de faire une sorte de wrapper IComparer<T> ... mais je ne suis pas en mesure de déterminer qui ou comment ils devraient travailler. Doivent se rappeler que cela pourrait donner tout type de comparateur aussi, donc techniquement les plages pourraient être dans le sens opposé, tant que le comparateur donné en tient compte bien sûr (Dans le code réel je jette une exception si le début est après la fin selon le comparateur donné). Quoi qu'il en soit, je suis un peu perdu ici: P

Était-ce utile?

La solution

Je pense que vous devez prendre en compte les valeurs nulles dans la comparaison.

serait-ce pas aider?

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, pour la deuxième partie. mettre en début et en fin de null, et seulement configuré pour démarrer / valeurs finales si les deux est non nulle.

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);
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top