Durch meinen guten Kollegen Stefan Lieser bin ich auf diese Seite gestoßen. Dort geht es darum, eine Enumeration nicht als enum zu verwenden, sondern eine Klasse zu bauen mit statischen Enumerations-Objekten. Die Klasse lässt sich verwenden wie eine normale Enumeration hat aber den Vorteil, dass man noch zusätzliche Attribute hinterlegen kann. Ich fand die Idee sehr interessant und habe mir überlegt, ob ich das für mich irgend wie einsetzen kann. Ursprünglich hatte ich für die Bewegungsrichtungen der Kugeln eine Enumeration mit allen möglichen Richtungen.
1: public enum Direction {
2: UpperLeft, 3: UpperRight, 4: Left, 5: Right, 6: LowerLeft, 7: LowerRight 8: } Das Problem daran ist, dass ich zu jeder Richtung wissen muss, ob die x/y Koordinate hoch oder runter gezählt werden muss oder ob sie gleich bleibt. Desweiteren muss ich zu einer Richtung die Gegenrichtung kennen.
Der erste Ansatz war eine Methode der den inkrementellen Wert für die Richtung über ein switch-case zurück gibt und ein Dictionary, dass als Schlüssel eine Direction hat und als Value die entsprechende Gegenrichtung.Viel schöner finde ich es, dass über die Enumeration-Klasse zu machen.
Hier die neue Implementierung der Direction:
1: public class Direction : Enumeration {
2: private readonly Func<Direction> inverseProjection;
3: public int Xincrement { get; private set; }
4: public int Yincrement { get; private set; }
5: 6: public Direction InverseDirection { get { return inverseProjection(); } }
7: 8: public Direction(string displayName, int xincrement, int yincrement, Func<Direction> inverseProjection)
9: : base(displayName) {
10: this.inverseProjection = inverseProjection;
11: Xincrement = xincrement; 12: Yincrement = yincrement; 13: } 14: 15: public static readonly Direction UpperLeft = new Direction("UpperLeft",-1,-1, () => LowerRight);
16: public static readonly Direction UpperRight = new Direction("UpperRight",0,-1, () => LowerLeft);
17: public static readonly Direction Left = new Direction("Left", -1,0, () => Right);
18: public static readonly Direction Right = new Direction("Right", 1, 0, () => Left);
19: public static readonly Direction LowerLeft = new Direction("LowerLeft", 0, 1, () => UpperRight);
20: public static readonly Direction LowerRight = new Direction("LowerRight", 1, 1, () => UpperLeft);
21: }Wie man sehen kann, wurde der Klasse X und Y Inkrement hinzugefügt. Die Erweiterung ist nicht sehr aufregend, da ich einfach im Konstruktor die entsprechende Konstante übergebe.
Viel interessanter ist die InverseDirection. Im ersten Versuch habe ich einfach im Konstruktor die entsprechende Gegenrichtung übergeben. Leider legt sich das Programm direkt auf die Nase, da zum Zeitpunkt der Zuweisung die Gegenrichtung noch NULL ist. Deshalb wird hier die Lambda Expression verwendet.Was man noch refactoren könnte ist, dass im Konstruktor keine nackten Zahlen mehr übergeben werden. Das Problem ist, dass nach mehreren Monaten keiner mehr weiß was “-1” bedeutet.
Das schöne ist, dass ich meine switch-case Anweisung und das Dictionary nun wegwerfen kann und der Code wesentlich sauberer aussieht. Im Gegensatz zu
1: private Ball GetNextBall(Direction dir, int posx, int posy) {
2: int xinc, yinc;
3: GetIncrement(dir, out xinc, out yinc);
4: if (IsOutOfField(posx + xinc, posy + yinc)) {
5: return null;
6: } 7: return GetBall(posx + xinc, posy + xinc);
8: } 1: private Ball GetNextBall(Direction dir, int posx, int posy) {
2: if (IsOutOfField(posx + dir.Xincrement, posy + dir.Yincrement)) {
3: return null;
4: } 5: return GetBall(posx + dir.Xincrement, posy + dir.Yincrement);
6: }1: private void GetIncrement(Direction dir, out int xinc, out int yinc){
2: switch(dir){
3: case Direction.UpperLeft:
4: xinc = -1; 5: yinc = -1; 6: break;
7: ...
Keine Kommentare:
Kommentar veröffentlichen