Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

25.08.2015, 08:50

C# | Vermeidung von Enums

Hallo Zusammen,

wie aus dem Titel hervorgeht, möchte ich gerne eure Meinung dazu wie man Enums vermeiden kann. Der Wunsch dazu ergibt sich aus einem Problem, das ich während der Spieleentwicklung habe. Folgend meine Einsatzgebiete für Enums.

Typ-Check
Wenn ich viele Objekte in einer Liste habe, die als Typ ein Interface hat, möchte ich beim entnehmen der Objekte gerne das Objekt wieder von einer spezifischen Klasse haben. Um nicht gegen jede Möglichkeit zu casten, gucke ich nach einem Enum.
Beispiel:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var waffe = new Waffe();
            var buch = new Buch();

            var items = new List<Item>();
            items.Add(waffe);
            items.Add(buch);

            foreach (var item in items)
            {
                switch (item.typ)
                {
                    case typ_enum.Waffe:
                        item = item as Waffe;
                    case typ_enum.Buch:
                        item = item as Buch; 
                    default:
                        break;
                }
            }


How To Handle
Mein zweites Einsatzgebiet von Enums ist, um zu gucken wie ich mit einem Objekt umgehen muss. Wenn ich das Beispiel von oben nehme, muss ich eine Waffe anders behandeln als ein Buch. Zu diesem Zweck gucke ich nach dem Enum und entscheide dann, welchen Handler ich nehme.

Das sind meine zwei Einsatzgebiete für selbst erstellte Enums. Beides finde ich nicht sehr schick, doch bis jetzt hatte ich (offensichtlich) keinen besseren Einfall. Ich hoffe ihr habt eine Idee, gerade weil das hinzufügen von neuen Werten bedeutet, das ich jedes einzelne Switch-Case anpassen muss. :)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Keiran Thackeray« (25.08.2015, 08:58)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

25.08.2015, 09:02

Wenn Du Bücher anders behandeln willst als Waffen, wieso liegen sie dann überhaupt in einer gemeinsamen Liste? Klingt für mich wenig sinnvoll.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

25.08.2015, 09:36

Wenn Du Bücher anders behandeln willst als Waffen, wieso liegen sie dann überhaupt in einer gemeinsamen Liste? Klingt für mich wenig sinnvoll.
Zum Beispiel im Inventar des Spielers oder Händlers. Dort verwende ich solche Listen um die Gegenstände zu verwahren. Wenn ich dem Spieler / Händler für jeden möglichen Item Typ eine Liste gebe, erscheint mir das etwas ungeschickt gelöst. Oder wäre das tatsächlich der Weg, den du empfehlen würdest ? :)

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

4

25.08.2015, 09:38

Ansonsten gibt es ein paar Möglichkeiten die du dir angucken kannst.
Erstens Polymorphie. Implementieren verschiedene Klassen das selbe Interface so können sie dennoch unterschiedlichen Code für die eigentliche Implementierung nutzen.
Zweitens Strategy. Strategy ist ein Entwurfsmuster bei welchem eine Methode als Klasse gekapselt injiziert wird.
Drittens Double Dispatch. Mit dieser Technik kannst du dir das casten sparen und direkt die eigentliche Klasse bekommen. Guck es dir einfach mal an. Double Dispatch sieht man oft im Zusammenhang mit dem Visitor Pattern. Ein Entwurfsmuster welches du dir auch mal ansehen könntest.
Viertens Dependency Injection. Die Bücher und Waffen könnten bei der Erzeugung eine Referenz auf den jeweiligen Handler mit bekommen bzw noch besser, die Waffe bzw das Buch bekommt nicht den Handler sondern die beiden werden an passender Stelle in Verbindung gebracht.

Dies sind einfach mal vier Möglichkeiten mit welchen du möglicherweise deine Probleme angehen kannst. Was BlueCobold sagt ist aber schon richtig. Objekte sollten zusammen gefasst werden eben weil sie gleich behandelt werden. Möglicherweise liegt dein Problem schon im grundlegenden Design.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

5

25.08.2015, 10:01

Ich vermute mal die Unterscheidung ist dafür da, um mit den Items unterschiedliche Aktionen durchzuführen, aber alle in einem Rucksack zu verwalten. Um die Enums zu umgehen könntest du deine Basisklasse im weitere Beschreibende Daten erweitern, z.B. ob es ein Item für die Hand oder den Arm ist, kann man es lesen usw. Dann musst du nicht den Typ, sondern Eigenschaften prüfen. Um die Implementierung zu vereinfachen könntest du dann Basisklassen erstellen, um einige Properties automatisch mit Werten zu besetzen, die in Ableitungen definitiv nicht benötigt werden und immer gleich sind.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

25.08.2015, 11:04

An der Stelle würde ich eventuell überhaupt keine Unterscheidung treffen. Ich würde allen Items die Properties "isEquipped" und "isEquippable" geben und eine Methode zum Berechnen der Boni, die sie dem Spieler geben. Dann kann es sogar Items geben, die einen Bonus selbst dann verleihen, wenn sie nur im Inventory liegen (man denke an Diablo 2 z.B.).
Einen Händler würde ich vermutlich eh so strukturieren, dass er Waffen, Rüstungen, Materials und Krimskams in separaten Regalen/Listen verkauft. Auch da ist kein Enum zur Unterscheidung notwendig.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

7

25.08.2015, 11:37

Ich kann mich da BlueCobold nur anschließen und werfe noch die Phrase "Composition over Inheritance" in den Raum.
Und es sollten bessere Namen in einer einheitlichen Sprache gewählt werden. "Item" ist englisch, "Buch" und "Waffe" ist deutsch und typ_enum sollte eher ItemType/ItemTypes oder GegenstandTyp/GegenstandTypen heißen.

Und passive Eigenschaften/Fähigkeiten gibt es auch in anderen Spielen, wie bspw. League of Legends.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

8

25.08.2015, 12:29

Mit den letzten Antworten von TrommlBomml und BlueCobold sehe ich einen guten Ansatz. Vielen dank dafür.
TrommlBomml
hat dabei auch noch einmal gut mein Problem zusammengefasst, genau so verhält es sich :)

@Sacaldur: Dein Einwand für die Vergabe der Namen ist natürlich richtig. Für dieses Beispiel habe ich allerdings darauf verzichtet richtige Namen zu geben, es kommt Ja auch so das Problem rüber. Zu dem geht es bei der Frage Ja auch nicht um die Namen, in einem echten Projekt würde ich Deutsch und Englisch natürlich nicht mischen. Im übrigen würde ich dann auch eher englische Namen empfehlen, so kann doch wenigstens jeder was damit anfangen ;)

Werbeanzeige