Liste von const int anstelle von enum

8

Ich begann mit der Arbeit an einer großen c # -Code-Basis und fand die Verwendung einer statischen Klasse mit mehreren const ints -Feldern. Diese Klasse verhält sich genau wie ein Enum.

Ich möchte die Klasse in eine tatsächliche enum umwandeln, aber die Kräfte, die gesagt werden, nein. Der Hauptgrund, warum ich es konvertieren möchte, ist so, dass ich die enum als Datentyp anstelle von int haben könnte. Dies würde viel zur Lesbarkeit beitragen.

Gibt es einen Grund, keine enums zu verwenden und stattdessen const ints zu verwenden? Dies ist zur Zeit der Code:

%Vor%

Aber ich denke, es sollte stattdessen folgendes sein:

%Vor%     
Telavian 08.09.2011, 17:26
quelle

5 Antworten

6

Ich denke, viele der Antworten hier ignorieren die Implikationen der Semantik von enums .

  • Sie sollten erwägen, eine Aufzählung zu verwenden, wenn die gesamte Menge aller gültigen Werte (Ids) im Voraus bekannt ist und klein genug ist, um im Programmcode deklariert zu werden.

  • Sie sollten in Erwägung ziehen, ein int zu verwenden, wenn die Menge bekannter Werte eine Teilmenge aller möglichen Werte ist - und der Code muss nur diese Teilmenge kennen.

Was das Refactoring betrifft - wenn Zeit und geschäftliche Einschränkungen es zulassen, ist es eine gute Idee, den Code zu bereinigen, wenn das neue Design / die Implementierung deutliche Vorteile gegenüber der vorherigen Implementierung hat und das Risiko gut verstanden wird. In Situationen, in denen der Nutzen gering oder das Risiko hoch ist (oder beides), kann es besser sein, die Position "do no harm" einzunehmen und nicht "kontinuierlich zu verbessern" . Nur Sie sind in der Lage zu beurteilen, welcher Fall auf Ihre Situation zutrifft.

Übrigens ist ein Fall, in dem keine enums oder Konstanteneinträge sind, eine gute Idee, wenn die IDs die Bezeichner von Datensätzen in einem externen Speicher darstellen (wie a Datenbank). Es ist oft riskant, solche IDs in der Programmlogik fest zu codieren, da diese Werte in verschiedenen Umgebungen (z. B. Test, Entwicklung, Produktion usw.) tatsächlich unterschiedlich sein können. In solchen Fällen kann das Laden der Werte zur Laufzeit eine geeignetere Lösung sein.

    
LBushkin 08.09.2011, 18:01
quelle
3

Ihre vorgeschlagene Lösung sieht elegant aus, funktioniert jedoch nicht so, wie sie ist, da Sie keine Instanzen eines statischen Typs verwenden können. Es ist etwas kniffliger, ein Enum zu emulieren.

Es gibt ein paar mögliche Gründe dafür, enum oder const-int für die Implementierung zu wählen, obwohl ich mir für das eigentliche Beispiel, das Sie gepostet haben, nicht viele starke vorstellen kann - auf den ersten Blick scheint es ein idealer Kandidat zu sein für ein enum.

Ein paar Ideen, die mir in den Sinn kommen, sind:

Enums

  • Sie bieten Typ-Sicherheit. Sie können keine alte Nummer übergeben, für die ein Aufzählungswert erforderlich ist.
  • Werte können automatisch generiert werden
  • Sie können reflection verwenden, um einfach zwischen den Werten und den Namen
  • zu konvertieren
  • Sie können die Werte in einer Enumeration in einer Schleife auf einfache Weise aufzählen, und wenn Sie neue enum-Member hinzufügen, berücksichtigt die Schleife sie automatisch.
  • Sie können neue Enunm-Werte einfügen, ohne sich Gedanken über Kollisionen machen zu müssen, wenn Sie versehentlich einen Wert wiederholen.

const-ints

  • Wenn Sie nicht verstehen, wie Sie Enums verwenden (z. B. nicht wissen, wie Sie den zugrunde liegenden Datentyp einer Enumeration ändern oder explizite Werte für Enumerationswerte festlegen oder mehreren Konstanten den gleichen Wert zuweisen) könnte fälschlicherweise glauben, dass du etwas erreichst, für das du keine enum verwenden kannst, indem du eine const.
  • verwendest
  • Wenn Sie an andere Sprachen gewöhnt sind, können Sie das Problem natürlich nur mit Problemen angehen, ohne zu erkennen, dass es eine bessere Lösung gibt.
  • Sie können von Klassen ableiten, um sie zu erweitern, aber ärgerlicherweise können Sie keine neue Enumeration von einer bestehenden ableiten (was ein wirklich nützliches Feature wäre). Möglicherweise könnten Sie also eine Klasse (aber nicht die in Ihrem Beispiel!) Verwenden, um eine "erweiterbare Enum" zu erreichen.
  • Sie können sich leicht umstellen. Wenn Sie eine Enumeration verwenden, müssen Sie möglicherweise ständig Daten (z. B.), die Sie von einer Datenbank erhalten, an den und vom Aufzählungstyp übergeben. Was Sie in Sachen Sicherheit verlieren, gewinnen Sie an Komfort. Zumindest bis du irgendwo die falsche Nummer passierst ...: -)
  • Wenn Sie readonly anstelle von const verwenden, werden die Werte in tatsächlichen Speicherbereichen gespeichert, die bei Bedarf gelesen werden. Auf diese Weise können Sie Konstanten in einer anderen Assembly veröffentlichen, die zur Laufzeit gelesen und verwendet werden, anstatt in die andere Assembly integriert zu sein. Dies bedeutet, dass Sie die abhängige Assembly nicht erneut kompilieren müssen, wenn Sie eine der Konstanten in Ihrer eigenen Assembly ändern. Dies ist eine wichtige Überlegung, wenn Sie in der Lage sein möchten, eine große Anwendung zu patchen, indem Sie nur Aktualisierungen für eine oder zwei Baugruppen veröffentlichen.
  • Ich denke, es ist ein Weg, um klarer zu machen, dass die Enum-Werte müssen unverändert bleiben. Mit einem Enum gibt ein anderer Programmierer einfach einen neuen Wert ein, ohne darüber nachzudenken, aber eine Liste von Konflikten lässt einen aufhorchen und denken: "Warum ist das so? Wie füge ich einen neuen Wert sicher hinzu?". Aber ich würde dies erreichen, indem ich explizite Werte auf die Enums lege und einen klaren Kommentar hinzufüge, anstatt auf Constants zurückzugreifen.

Warum sollten Sie die Implementierung in Ruhe lassen?

  • Der Code wurde möglicherweise von einem Idioten geschrieben, der keinen guten Grund für das hat, was er getan hat. Aber seinen Code zu ändern und ihm zu zeigen, dass er ein Idiot ist, ist kein kluger oder hilfreicher Zug.
  • Es kann einen guten Grund geben, dass es so ist, und Sie werden etwas kaputt machen, wenn Sie es ändern (zB muss es eine Klasse sein, weil es durch Reflektion zugänglich gemacht wird, durch externe Interfaces zugänglich gemacht wird oder um Leute einfach zu serialisieren) die Werte, weil sie durch das verwendete Verschleierung System gebrochen werden. Kein Ende von unnötigen Fehlern wird von Leuten in Systeme eingeführt, die nicht vollständig verstehen, wie etwas funktioniert, besonders wenn sie nicht wissen, wie sie ihre Änderungen testen können, um sicherzustellen, dass sie nichts kaputt gemacht haben.
  • Die Klasse wird möglicherweise automatisch von einem externen Tool generiert. Sie müssen also das Tool reparieren, nicht den Quellcode.
  • Vielleicht gibt es einen Plan, in Zukunft mit dieser Klasse mehr zu tun (?!)
  • Auch wenn Änderungen sicher sind, müssen Sie alles, was von der Änderung betroffen ist, erneut testen. Wenn der Code so funktioniert wie er ist, lohnt sich der Gewinn? Wenn wir an Legacy-Systemen arbeiten, werden wir oft existierenden Code schlechter Qualität sehen oder einfach so, wie wir es persönlich nicht mögen, und wir müssen akzeptieren, dass es nicht kosteneffektiv ist, es zu "reparieren", egal wie sehr es sich nagt. Natürlich könntest du auch ein "Ich habe es dir gesagt!" wenn die const-basierte Implementierung aufgrund fehlender Typ-Sicherheit fehlschlägt. Aber abgesehen von der Typensicherheit ist die Implementierung letztlich nicht weniger effizient oder effektiv als ein Enum.
Jason Williams 08.09.2011 19:57
quelle
1

Wenn es nicht kaputt ist, repariere es nicht.

Ich kenne das Design des Systems, an dem Sie gerade arbeiten, nicht, aber ich vermute, dass die Felder Integer sind, die zufällig eine Reihe vordefinierter Werte haben. Das heißt, sie könnten in einem zukünftigen Zustand mehr als diese vordefinierten Werte enthalten. Während ein enum dieses Szenario (über Casting) zulässt, bedeutet dies, dass nur die Werte gültig sind, die die Enumeration enthält.

Insgesamt ist die Änderung semantisch, aber unnötig. Unnötige Änderungen wie diese sind oft eine Fehlerquelle, zusätzlicher Testaufwand und andere Kopfschmerzen mit nur geringen Vorteilen. Ich sage, fügen Sie einen Kommentar hinzu, der ausdrückt, dass dies ein enum sein könnte und lassen Sie es so wie es ist.

    
Jeff Yates 08.09.2011 17:31
quelle
0

Ja, es hilft bei der Lesbarkeit, und nein, ich kann mir keinen Grund dafür vorstellen.

Die Verwendung von const int ist eine sehr "alte Schule" der Programmierpraxis für C ++.

    
Jeff 08.09.2011 17:30
quelle
0

Der Grund, den ich sehe, ist, dass Sie, wenn Sie locker mit einem anderen System verbunden sein wollen, das die gleichen Konstanten verwendet, vermeiden, eng gekoppelt zu sein und den gleichen Aufzählungstyp zu teilen.

Wie in RPC-Aufrufen oder etwas ...

    
quelle

Tags und Links