LinkedList Dojo mit Visual T# – Teil 2

Karate

Image courtesy of „luigi diamanti“ / FreeDigitalPhotos.net


Dies ist der zweite Teil von „LinkedList Dojo mit Visual T#“. In dieser Übungsaufgabe implementieren wir eine verknüpfte Liste nach dem Test-First Ansatz mit Hilfe von Visual T#.

Greifen Sie ruhig zu

Im ersten Teil haben wir die Funktion Add() und das Property Count implementiert. Nun wollen wir überprüfen, ob die Daten auch richtig abgelegt wurden. Dazu benötigen wir den Index-Operator (manchmal auch Indexer genannt) this[int index].

Als erstes wiederum ein Test, um eine erste Implementation zu erzwingen.

1
2
3
4
5
6
7
8
9
test this[int index] get
{
    LinkedList sut = new LinkedList ();
    sut.Add(5);

    runtest int value = sut[0];

    assert value == 5;
}

Und hier die zum Test passende Implementation.

1
2
3
4
5
6
7
8
9
10
11
public T this[int index]
{
    get
    {
        return first.Element;
    }
    set
    {
        throw new NotImplementedException();
    }
}

Schon beim Schreiben des Codes ist die nächste Frage aufgetaucht: Wie soll sich die Liste verhalten, wenn noch kein Element vorhanden ist oder wenn ein Index verwendet wird, der grösser ist als die Anzahl der Elemente in der Liste?
Die Dokumentation von IList<T> verrät es uns (im Bereich Exceptions):

ArgumentOutOfRangeException:
index is not a valid index in the IList<T>.

Dies hat zwei weitere Tests zur Folge:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
test this[int index] get
{
    LinkedList sut = new LinkedList ();

    runtest int value = sut[0];

    assert thrown ArgumentOutOfRangeException;
}
       
test this[int index] get
{
    LinkedList sut = new LinkedList ();
    sut.Add(5);
    sut.Add(8);

    runtest int value = sut[2];

    assert thrown ArgumentOutOfRangeException;
}

Und dazu natürlich noch die passende Implementation, so dass die Tests auch wieder grün werden.

1
2
3
4
5
6
7
8
9
10
public T this[int index]
{
    get
    {
        if (index &gt;= Count) throw new ArgumentOutOfRangeException();
        return first.Element;
    }
    set
    (...)
}

Gezielter Zugriff

Natürlich funktioniert der Indexer bisher nur beim ersten Element richtig. Fügen wir also einen Test hinzu, um den wahlfreien Zugriff zu ermöglichen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
test this[int index] get
{
    int value1, value2;  
    LinkedList sut = new LinkedList ();
    for(int i = 0; i = Count) throw new ArgumentOutOfRangeException();

        LinkedListElement temp = first;

        for(int i = 0; i &lt; index; i++)
        {
            temp = temp.Next;
        }

        return temp.Element;
    }
    set
    (...)
}

Fehlt noch die Implementation des Setters, als erstes wieder der Test.

test this[int index] set
{
    int value1, value2;  
    LinkedList sut = new LinkedList ();
    for(int i = 0; i = Count) throw new ArgumentOutOfRangeException();

        LinkedListElement temp = first;

        for (int i = 0; i &lt; index; i++)
        {
            temp = temp.Next;
        }

        temp.Element = value;
    }
}

OK, bei der Implementation habe ich etwas geschummelt, ich habe das Test-First Prinzip missachtet und bereits die Überprüfung, ob der übergebene index gültig ist, eingebaut. Hier noch der Test, um die Überprüfung auch zu rechtfertigen.

 test this[int index] set
{
    LinkedList sut = new LinkedList ();
    sut.Add(5);
    sut.Add(8);
           
    runtest sut[2] = 3;

    assert thrown ArgumentOutOfRangeException;
}

Was mich aber mehr stört als die kleine Prinzip-Verletzung sind die Redundanzen im Code, am offensichtlichsten im zuletzt implementierten Indexer. Deshalb starten wir den dritten Teil mit einem Refactoring der bisher implementieren Funktionalitäten und Tests.

3 Gedanken zu „LinkedList Dojo mit Visual T# – Teil 2

  1. Pingback: LinkedList Dojo mit Visual T# – Teil 1 « of bits and bytes

  2. Pingback: LinkedList Dojo mit Visual T# – Teil 3 « of bits and bytes

  3. Pingback: IList Dojo Retrospektive « of bits and bytes

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.