Ein eigener Datentyp (Teil 2)

Im letzten Teil (siehe: Ein eigener Datentyp (Teil1)) haben wir uns mit dem Grundgerüst unseres Datentypen zufrieden gegeben. Diesmal sollen die Operatoren implementiert werden. Der wohl wichtigste Operator hierfür dürfte der „implicit“-Operator oder auch Zuweisungsoperator sein. Auch hier werden wir wieder zwischen einem normalen Integer-Wert und einem Byte-Array unterscheiden und zwei Implementierungen vornehmen. Trotz der enormen Wichtigkeit dieses Operators ist dieser dennoch sehr simpel zu implementieren.

public static implicit operator Int24(int value)
{
    return new Int24(value);
}

public static implicit operator Int24(byte[] value)
{
    return new Int24(value);
}

Wie im Sourcecode zu sehen wird nur eine neue Instanz eines 24-Bit Integers erzeugt und zurück gegeben. Da wir bereits die nötigen Konstruktoren implementiert haben, haben wir keinen Aufwand mehr mit dieser Methode. 

Weiter geht es mit einem nicht ganz so oft verwendetem, aber dennoch hin und wieder notwendigen Operator, die Tilde. Diese ist funktionsgleich mit einem XOR über ein voll besetztes Byte (Beispiel 192 XOR 255 = 63). Obwohl sich dies schon etwas komplizierter anhört, ist auch diese Implementierung dadurch simpel, dass uns jedes Byte den Operator selbst zur Verfügung stellt.

public static Int24 operator ~(Int24 value)
{
    byte[] dataBytes = value.ToByteArray();
    return new Int24(new[]
                            {
                                (byte)(~dataBytes[0]), (byte)(~dataBytes[1]), (byte)(~dataBytes[2])
                            });
}

Wie gerade bereits bemerkt bediene ich mich nun einer noch nicht vorhandenen Methode „ToByteArray“, welche nun zwischenzeitig implementiert wird. Aber auch hier sind es simple Ein-Zeiler.

public byte[] ToByteArray()
{
    return _value;
}

public static Int24 FromByteArray(byte[] dataBytes)
{
    return new Int24(dataBytes);
}

Weiter geht es nun mit den Grundrechenarten (Addition, Subtraktion, Multiplikation und Division sowie zusätzlich Modulo). Hier können wir uns jeweils der Implementierung vom Int32 bedienen, welchen wir über das Value erreichen und auch so haben wir hier ebenfalls ein leichtes spiel.

public static Int24 operator +(Int24 value1, Int24 value2)
{
    return new Int24(value1.Value + value2.Value);
}

public static Int24 operator -(Int24 value1, Int24 value2)
{
    return new Int24(value1.Value - value2.Value);
}

public static Int24 operator *(Int24 value1, Int24 value2)
{
    return new Int24(value1.Value * value2.Value);
}

public static Int24 operator /(Int24 value1, Int24 value2)
{
    return new Int24(value1.Value / value2.Value);
}

public static Int24 operator %(Int24 value1, Int24 value2)
{
    return new Int24(value1.Value % value2.Value);
}

Zum Abschluss noch Inkrement sowie Dekrement Operatoren:

public static Int24 operator ++(Int24 value)
{
    value += 1;
    return value;
}

public static Int24 operator --(Int24 value)
{
    value -= 1;
    return value;
}

Im nächsten Teil geht es mit den Vergleichsoperatoren weiter.