it-swarm-eu.dev

Sind #Regionen ein Antimuster- oder Codegeruch?

C # erlaubt die Verwendung von #region/#endregion Schlüsselwörter, um Codebereiche im Editor zusammenklappbar zu machen. Immer wenn ich dies tue, verstecke ich große Codestücke, die wahrscheinlich in andere Klassen oder Methoden umgestaltet werden könnten. Zum Beispiel habe ich Methoden gesehen, die 500 Codezeilen mit 3 oder 4 Regionen enthalten, um sie handhabbar zu machen.

Ist der umsichtige Umgang mit Regionen ein Zeichen von Ärger? Es scheint mir so zu sein.

274
Craig

Ein Codegeruch ist ein Symptom, das darauf hinweist, dass es ein Problem im Design gibt, das möglicherweise die Anzahl der Fehler erhöht: Dies ist nicht für Regionen der Fall, aber Regionen können dazu beitragen, Codegerüche wie lange Methoden zu erzeugen.

Schon seit:

Ein Anti-Pattern (oder Antipattern) ist ein Muster, das im sozialen oder geschäftlichen Betrieb oder im Software-Engineering verwendet wird und häufig verwendet wird, in der Praxis jedoch unwirksam und/oder kontraproduktiv ist

regionen sind Anti-Muster. Sie erfordern mehr Arbeit, die die Qualität oder Lesbarkeit des Codes nicht erhöht, die Anzahl der Fehler nicht verringert und den Code möglicherweise nur komplizierter für die Umgestaltung macht.

Verwenden Sie keine Regionen innerhalb von Methoden. Refactor stattdessen

Methoden müssen kurz sein . Wenn eine Methode nur zehn Zeilen enthält, würden Sie wahrscheinlich keine Regionen verwenden, um fünf davon auszublenden, wenn Sie an anderen fünf arbeiten.

Außerdem muss jede Methode eins und eins tun . Regionen hingegen sollen verschiedene Dinge trennen . Wenn Ihre Methode A und dann B ausführt, ist es logisch, zwei Regionen zu erstellen. Dies ist jedoch ein falscher Ansatz. Stattdessen sollten Sie die Methode in zwei separate Methoden umgestalten.

Die Verwendung von Regionen kann in diesem Fall auch das Refactoring erschweren. Stellen Sie sich vor, Sie haben:

private void DoSomething()
{
    var data = LoadData();
    #region Work with database
    var verification = VerifySomething();
    if (!verification)
    {
        throw new DataCorruptedException();
    }

    Do(data);
    DoSomethingElse(data);
    #endregion

    #region Audit
    var auditEngine = InitializeAuditEngine();
    auditEngine.Submit(data);
    #endregion
}

Das Reduzieren der ersten Region, um sich auf die zweite zu konzentrieren, ist nicht nur riskant: Wir können leicht die Ausnahme vergessen, die den Fluss stoppt (es könnte stattdessen eine Schutzklausel mit einem return geben, die noch schwieriger zu erkennen ist). hätte aber auch ein problem wenn der code folgendermaßen überarbeitet werden sollte:

private void DoSomething()
{
    var data = LoadData();
    #region Work with database
    var verification = VerifySomething();
    var info = DoSomethingElse(data);

    if (verification)
    {
        Do(data);
    }

    #endregion

    #region Audit
    var auditEngine = InitializeAuditEngine(info);
    auditEngine.Submit(
        verification ? new AcceptedDataAudit(data) : new CorruptedDataAudit(data));
    #endregion
}

Jetzt machen Regionen keinen Sinn, und Sie können den Code in der zweiten Region unmöglich lesen und verstehen, ohne den Code in der ersten zu betrachten.

Ein anderer Fall, den ich manchmal sehe, ist dieser:

public void DoSomething(string a, int b)
{
    #region Validation of arguments
    if (a == null)
    {
        throw new ArgumentNullException("a");
    }

    if (b <= 0)
    {
        throw new ArgumentOutOfScopeException("b", ...);
    }
    #endregion

    #region Do real work
    ...
    #endregion
}

Es ist verlockend, Regionen zu verwenden, wenn die Argumentvalidierung mehrere zehn LOC umfasst. Es gibt jedoch einen besseren Weg, um dieses Problem zu lösen: den vom .NET Framework-Quellcode verwendeten:

public void DoSomething(string a, int b)
{
    if (a == null)
    {
        throw new ArgumentNullException("a");
    }

    if (b <= 0)
    {
        throw new ArgumentOutOfScopeException("b", ...);
    }

    InternalDoSomething(a, b);
}

private void InternalDoSomething(string a, int b)
{
    ...
}

Verwenden Sie keine Regionen außerhalb von Methoden zum Gruppieren

  • Einige Leute verwenden sie, um Felder, Eigenschaften usw. Zu gruppieren. Dieser Ansatz ist falsch: Wenn Ihr Code StyleCop-kompatibel ist, dann Felder, Eigenschaften, privat Methoden, Konstruktoren usw. sind bereits zusammengefasst und leicht zu finden. Wenn dies nicht der Fall ist, ist es an der Zeit, über die Anwendung von Regeln nachzudenken, die die Einheitlichkeit Ihrer Codebasis gewährleisten.

  • Andere Leute verwenden Regionen, um viele ähnliche Entitäten zu verbergen . Wenn Sie beispielsweise eine Klasse mit hundert Feldern haben (was mindestens 500 Codezeilen ergibt, wenn Sie die Kommentare und das Leerzeichen zählen), könnten Sie versucht sein, diese Felder in eine Region einzufügen, sie zu reduzieren und sie zu vergessen. Auch hier machen Sie es falsch: Bei so vielen Feldern in einer Klasse sollten Sie besser über die Verwendung der Vererbung nachdenken oder das Objekt in mehrere Objekte aufteilen.

  • Schließlich sind einige Leute versucht, Regionen zu verwenden, um verwandte Dinge zu gruppieren : ein Ereignis mit seinem Delegaten oder eine Methode, die sich auf IO mit anderen Methoden im Zusammenhang mit E/A usw. Im ersten Fall wird es zu einem Durcheinander, das schwer zu pflegen, zu lesen und zu verstehen ist. Im zweiten Fall wäre das bessere Design wahrscheinlich, mehrere Klassen zu erstellen.

Gibt es eine gute Verwendung für Regionen?

Nein. Es gab eine Legacy-Verwendung: generierter Code. Tools zur Codegenerierung müssen jedoch stattdessen nur Teilklassen verwenden. Wenn C # Regionen unterstützt, liegt dies hauptsächlich daran, dass diese Legacy-Verwendung verwendet wird und dass jetzt, da zu viele Personen Regionen in ihrem Code verwendet haben, es unmöglich ist, sie zu entfernen, ohne vorhandene Codebasen zu beschädigen.

Betrachten Sie es als goto. Die Tatsache, dass die Sprache oder IDE eine Funktion unterstützt) nicht bedeutet, dass sie täglich verwendet werden sollte. Die StyleCop SA1124-Regel ist klar: Sie sollten sie nicht verwenden Regionen. Niemals.

Beispiele

Ich mache gerade eine Codeüberprüfung des Codes meines Kollegen. Die Codebasis enthält viele Regionen und ist tatsächlich ein perfektes Beispiel dafür, wie Regionen nicht verwendet werden und warum Regionen zu schlechtem Code führen. Hier sind einige Beispiele:

4 000 LOC-Monster:

Ich habe kürzlich irgendwo auf Programmers.SE gelesen, dass wenn eine Datei zu viele usings enthält (nachdem der Befehl "Unbenutzte Verwendungen entfernen" ausgeführt wurde), dies ein gutes Zeichen dafür ist, dass die Klasse in dieser Datei zu viel tut. Gleiches gilt für die Größe der Datei selbst.

Bei der Überprüfung des Codes bin ich auf eine 4 000 LOC-Datei gestoßen. Es stellte sich heraus, dass der Autor dieses Codes einfach dieselbe 15-Zeilen-Methode hunderte Male kopiert und eingefügt hat, wobei die Namen der Variablen und der aufgerufenen Methode geringfügig geändert wurden. Ein einfacher regulärer Ausdruck, mit dem die Datei von 4 000 LOC auf 500 LOC gekürzt werden kann, indem nur einige Generika hinzugefügt werden. Ich bin mir ziemlich sicher, dass diese Klasse mit einem clevereren Refactoring auf ein paar Dutzend Zeilen reduziert werden kann.

Durch die Verwendung von Regionen ermutigte sich der Autor, die Tatsache zu ignorieren, dass der Code nicht gepflegt und schlecht geschrieben werden kann, und den Code stark zu duplizieren, anstatt ihn umzugestalten.

Region "Do A", Region "Do B":

Ein weiteres hervorragendes Beispiel war eine Monsterinitialisierungsmethode, die einfach Aufgabe 1, dann Aufgabe 2, dann Aufgabe 3 usw. ausführte. Es gab fünf oder sechs Aufgaben, die völlig unabhängig waren und jeweils etwas in einer Containerklasse initialisierten. Alle diese Aufgaben wurden in einer Methode und in Regionen zusammengefasst.

Dies hatte einen Vorteil:

  • Die Methode war anhand der Regionsnamen ziemlich klar zu verstehen. Abgesehen davon wäre dieselbe Methode, die einmal überarbeitet wurde, so klar wie das Original.

Andererseits gab es mehrere Probleme:

  • Es war nicht offensichtlich, ob es Abhängigkeiten zwischen den Regionen gab. Hoffentlich gab es keine Wiederverwendung von Variablen; Andernfalls könnte die Wartung noch mehr zum Albtraum werden.

  • Die Methode war nahezu unmöglich zu testen. Wie würden Sie leicht wissen, ob die Methode, die zwanzig Dinge gleichzeitig ausführt, sie richtig macht?

Feldregion, Eigenschaftenregion, Konstruktorregion:

Der überprüfte Code enthielt auch viele Regionen, in denen alle Felder, alle Eigenschaften usw. zusammengefasst waren. Dies hatte ein offensichtliches Problem: das Wachstum des Quellcodes.

Wenn Sie eine Datei öffnen und eine große Liste von Feldern sehen, neigen Sie eher dazu, zuerst die Klasse umzugestalten und dann mit Code zu arbeiten. Bei Regionen haben Sie die Angewohnheit, Dinge zusammenzubrechen und zu vergessen.

Ein weiteres Problem ist, dass Sie, wenn Sie es überall tun, Regionen mit einem Block erstellen, was keinen Sinn ergibt. Dies war tatsächlich in dem von mir überprüften Code der Fall, in dem viele #region Constructor Einen Konstruktor enthielten.

Schließlich Felder, Eigenschaften, Konstruktoren usw. sollte bereits in Ordnung sein . Wenn dies der Fall ist und sie mit den Konventionen übereinstimmen (Konstanten, die mit einem Großbuchstaben beginnen usw.), ist bereits klar, wo ein Elementtyp aufhört und andere beginnt, sodass Sie dafür keine expliziten Regionen erstellen müssen.

291

Es ist unglaublich für mich, wie viele Menschen hassen Regionen so leidenschaftlich!

Ich stimme völlig mit so vielen ihrer Einwände überein: Code in ein #region es vor der Ansicht zu verbergen ist eine schlechte Sache. Teilen einer Klasse in #regions wann es in separate Klassen umgestaltet werden sollte, ist eindeutig ein Fehler. Verwendung einer #region redundante semantische Informationen einzubetten ist gut redundant.

Aber keines dieser Dinge bedeutet, dass irgendetwas von Natur aus falsch ist, wenn Regionen in Ihrem Code verwendet werden! Ich kann nur davon ausgehen, dass die Einwände der meisten Menschen darauf zurückzuführen sind, dass sie in Teams gearbeitet haben, in denen andere dazu neigen, IDE Funktionen wie diese falsch zu verwenden. Ich habe den Luxus, selbst primär zu arbeiten, und ich schätze das Wie Regionen dazu beigetragen haben, meinen Workflow zu organisieren. Vielleicht ist es meine Zwangsstörung, aber ich mag es nicht, wenn gleichzeitig eine Menge Code auf meinem Bildschirm angezeigt wird, egal wie ordentlich und elegant es geschrieben sein mag In logische Bereiche kann ich den Code reduzieren, den ich nicht kümmere, um an dem Code zu arbeiten, den ich nicht kümmere. Ich ignoriere schlecht geschriebenen Code nicht, es macht keinen Sinn, ihn mehr zu überarbeiten als er ist, und die zusätzliche "Meta" -Organisation ist eher beschreibend als sinnlos.

Jetzt, da ich mehr Zeit in C++ verbracht habe und direkter auf die Windows-API programmiert habe, wünsche ich mir, dass die Unterstützung für Regionen genauso gut ist wie für C #. Sie könnten argumentieren, dass die Verwendung einer alternativen GUI-Bibliothek meinen Code einfacher oder klarer machen würde, wodurch die Notwendigkeit entfällt, irrelevantes Code-Rauschen vom Bildschirm zu entfernen, aber ich habe andere Gründe, dies nicht zu tun. Ich beherrsche meine Tastatur und IDE, dass das Erweitern/Reduzieren des in Regionen unterteilten Codes weniger als einen Bruchteil einer Sekunde dauert. Die Zeit, die ich an Gehirnleistung spare, um meinen bewussten Fokus einzuschränken Nur der Code, an dem ich gerade arbeite, ist mehr als wert. Es gehört alles in eine einzelne Klasse/Datei, aber es gehört nicht alles gleichzeitig auf meinen Bildschirm.

Der Punkt ist, dass mit #regions Ihren Code zu trennen und logisch zu teilen, ist keine schlechte Sache, die Sie unbedingt vermeiden sollten. Wie Ed betont, ist es kein "Code-Geruch". Wenn Ihr Code riecht, können Sie sicher sein, dass er nicht aus den Regionen stammt, sondern aus dem Code, den Sie in diesen Regionen begraben möchten. Wenn eine Funktion Ihnen hilft, besser organisiert zu sein oder besseren Code zu schreiben, dann sage ich benutze sie. Wenn es zu einem Hindernis wird oder Sie feststellen, dass Sie es falsch verwenden, dann Stopp Verwenden Sie es. Wenn das Schlimmste zum Schlimmsten kommt und Sie gezwungen sind, in einem Team mit Personen zu arbeiten, die es verwenden, merken Sie sich die Tastenkombination, um die Code-Gliederung zu deaktivieren: Ctrl+MCtrl+P. Und hör auf dich zu beschweren. Manchmal habe ich das Gefühl, dass dies eine andere Art ist, wie diejenigen, die als "wahre", "Hardcore" -Programmierer gesehen werden wollen, gerne versuchen, sich zu beweisen. Sie sind nicht besser dran, Regionen zu meiden, als Syntaxfarben zu vermeiden. Es macht dich nicht zu einem Macho-Entwickler.

Abgesehen davon sind Regionen innerhalb Eine Methode nur Unsinn. Jedes Mal, wenn Sie dies möchten, sollten Sie eine separate Methode verwenden. Keine Ausreden.

115
Cody Gray

Zunächst einmal kann ich den Begriff "Codegeruch" nicht mehr ertragen. Es wird zu oft verwendet und wird häufig von Leuten verwendet, die keinen guten Code erkennen konnten, wenn er sie biss. Sowieso...

Ich persönlich mag es nicht, viele Regionen zu nutzen. Es macht es schwieriger, an den Code zu gelangen, und der Code interessiert mich. Ich mag Regionen, in denen ich einen großen Codeabschnitt habe, der nicht sehr oft berührt werden muss. Abgesehen davon scheinen sie mir nur im Weg zu stehen, und Regionen wie "Private Methoden", "Öffentliche Methoden" usw. machen mich einfach verrückt. Sie ähneln Kommentaren der Sorte i++ //increment i.

Ich möchte auch hinzufügen, dass die Verwendung von Regionen nicht wirklich ein "Anti-Pattern" sein kann, da dieser Begriff üblicherweise zur Beschreibung von Programmlogik-/Entwurfsmustern verwendet wird, nicht für das Layout eines Texteditors. Das ist subjektiv; Verwenden Sie, was für Sie funktioniert. Sie werden aufgrund Ihrer übermäßigen Nutzung von Regionen niemals mit einem nicht wartbaren Programm enden, worum es bei Anti-Patterns geht. :) :)

70
Ed S.

Ja, Regionen riechen nach Code!

Ich würde mich freuen, wenn Regionen vollständig aus dem Compiler entfernt würden. Jeder Entwickler hat sein eigenes sinnloses Pflegeprogramm entwickelt, das für einen anderen Programmierer niemals von Wert sein wird. Ich habe alles mit Programmierern zu tun, die ihr Baby dekorieren und verschönern wollen, nichts mit wirklichem Wert.

Können Sie sich ein Beispiel vorstellen, bei dem Sie allerdings "Meine Güte, ich wünschte, mein Kollege hätte hier einige Regionen genutzt!"?

Obwohl ich mein IDE) so konfigurieren kann, dass alle Regionen automatisch erweitert werden, sind sie immer noch augenschmerzhaft und beeinträchtigen das Lesen des echten Codes.

Es wäre mir wirklich egal, ob alle meine öffentlichen Methoden zusammengefasst sind oder nicht. Herzlichen Glückwunsch, Sie kennen den Unterschied zwischen einer Variablendeklaration und einer Initialisierung. Sie müssen sie nicht im Code anzeigen!

Wertlose Pflege!

Wenn Ihre Datei Anforderungen und 'Informationsarchitektur' durch die Verwendung von Regionen benötigt, möchten Sie möglicherweise das Kernproblem bekämpfen: Ihre Klasse ist viel zu groß! Das Aufteilen in kleinere Teile ist viel vorteilhafter und fügt bei richtiger Ausführung eine echte Semantik/Lesbarkeit hinzu.

23
Joppe

Ich persönlich benutze Regionen, um verschiedene Arten von Methoden oder Codeteilen zu gruppieren.

Eine Codedatei könnte also beim Öffnen folgendermaßen aussehen:

  • Öffentliche Eigenschaften
  • Konstruktoren
  • Methoden speichern
  • Methoden bearbeiten
  • Private Hilfsmethoden

Ich setze keine Regionen in Methoden ein. IMHO ist das ein Zeichen von Code-Geruch. Ich bin einmal auf eine Methode gestoßen, die über 1200 Zeilen lang war und 5 verschiedene Regionen enthielt. Es war ein beängstigender Anblick!

Wenn Sie es verwenden, um Ihren Code so zu organisieren, dass andere Entwickler schneller nach Dingen suchen, ist dies meines Erachtens kein Anzeichen für Probleme. Wenn Sie damit Codezeilen innerhalb einer Methode ausblenden, ist es an der Zeit, diese Methode zu überdenken.

15
Tyanna

Verwenden von #region Blöcke, um eine sehr große Klasse lesbar zu machen, sind normalerweise ein Zeichen für einen Verstoß gegen das Prinzip der Einzelverantwortung. Wenn sie verwendet werden, um Verhalten zu gruppieren, ist es auch wahrscheinlich, dass die Klasse zu viel tut (erneut gegen SRP verstößt).

Bleiben Sie bei der Gedankenrichtung "Codegeruch", #region Blöcke sind keine Code-Gerüche an und für sich, sondern eher "Febreze for Code", da sie versuchen, Gerüche zu verbergen. Während ich sie in der Vergangenheit eine Tonne benutzt habe, sehen Sie beim Umgestalten weniger, weil sie sich am Ende nicht viel verstecken.

10
Austin Salonen

Das Schlüsselwort hier ist "vernünftig". Es ist schwer vorstellbar, dass es sinnvoll ist, eine Region in eine Methode einzubeziehen. das ist allzu wahrscheinlich Code-Verstecken und Faulheit. Es kann jedoch gute Gründe geben, hier und da einige Regionen im eigenen Code zu haben.

Wenn es viele, viele Regionen gibt, denke ich, dass das ein Code-Geruch ist. Regionen sind oft ein Hinweis auf einen möglichen Ort für zukünftiges Refactoring. Viele Regionen bedeuten, dass jemand den Hinweis nie wirklich versteht.

Mit Bedacht eingesetzt, bieten sie einen guten Mittelweg zwischen der Struktur einer einzelnen Klasse mit vielen Methoden und der Struktur vieler Klassen mit jeweils nur wenigen Methoden. Sie sind am nützlichsten, wenn eine Klasse sich dem Punkt nähert, an dem sie in mehrere Klassen umgestaltet werden soll, aber noch nicht ganz da ist. Durch die Gruppierung verwandter Methoden mache ich es später einfach, eine Reihe verwandter Methoden in ihre eigene Klasse zu extrahieren, wenn ihre Anzahl weiter zunimmt. Wenn ich beispielsweise eine Klasse habe, die sich 500 Codezeilen nähert, ist dieser Methodensatz, bei dem insgesamt 200 Codezeilen in einer Region gesammelt werden, wahrscheinlich ein gutes Stück, um ihn irgendwie umzugestalten - und diese andere Region mit 100 Codezeilen Methoden könnten auch ein gutes Ziel sein.

Eine andere Möglichkeit, Regionen zu verwenden, besteht darin, einen der negativen Auswirkungen der Umgestaltung einer großen Methode zu verringern: Viele kleine, präzise und leicht wiederverwendbare Methoden, durch die ein Leser scrollen muss, um zu einer anderen, meist nicht verwandten Methode zu gelangen. Eine Region kann eine gute Möglichkeit sein, eine Methode und ihre Helfer für die Leser meta-zu kapseln, sodass jemand, der mit einem anderen Aspekt der Klasse arbeitet, diese einfach reduzieren und diesen Teil des Codes schnell verwerfen kann. Dies funktioniert natürlich nur, wenn Ihre Regionen wirklich gut organisiert sind und im Wesentlichen als eine andere Möglichkeit zur Dokumentation Ihres Codes verwendet werden.

Im Allgemeinen finde ich Regionen, die mir helfen, mich selbst zu organisieren, meinen Code zu "dokumentieren" und Orte zu finden, an denen Refactor viel früher durchgeführt werden kann, als wenn ich keine Regionen verwende.

5
Ethel Evans

Ich verwende hauptsächlich Regionen für CRUD-Serverklassen, um die verschiedenen Arten von Operationen zu organisieren. Selbst dann könnte ich gerne ohne sie gehen.

Bei ausgiebiger Verwendung würde eine rote Fahne gehisst. Ich würde nach Klassen Ausschau halten, die zu viel Verantwortung haben.

Nach meiner Erfahrung ist eine Methode mit Hunderten von Zeilen pro Code definitiv ein Geruch.

4
TaylorOtwell

Meine Faustregel lautet: Wenn Sie mehr als 5 Regionen in einer Datei haben, riecht es nach Code

Das heißt, es mag in Ordnung sein, Felder, Methoden, Eigenschaften und Konstruktoren abzugrenzen, aber wenn Sie anfangen, jede andere Methode in eine eigene Region zu verpacken, stimmt etwas nicht

..und ja, ich war an vielen Projekten beteiligt, bei denen dies der Fall ist, häufig aufgrund schlechter Codierungsstandards, Codegenerierung oder beidem. Es wird schnell alt, alle Umrisse in Visual Studio umzuschalten, um einen guten Überblick über den Code zu erhalten.

4
Homde

REGIONEN HABEN IHRE NUTZUNG

Ich habe sie persönlich für "Handcodierung" von Schnittstellenereignissen verwendet, bevor ich Windows Forms-Apps verwendet habe.

Bei meiner Arbeit verwenden wir jedoch einen Codegenerator für den Umgang mit SQL und er verwendet automatisch Regionen, um die Arten von Methoden zum Auswählen, Aktualisieren, Löschen usw. zu sortieren.

Obwohl ich sie nicht oft benutze, eignen sie sich perfekt zum Entfernen großer Codestücke.

4
Ken

Wenn Sie Regionen IN Code haben, haben Sie sicherlich ein Problem (mit Ausnahme des generierten Codes). Wenn Sie Regionen in Code einfügen, heißt das im Grunde "refactor this".

Es gibt jedoch auch andere Fälle. Eines, das mir vor einiger Zeit in den Sinn gekommen ist: Ein Tisch mit ein paar tausend vorberechneten Gegenständen. Es ist eine Beschreibung der Geometrie, abgesehen von einem Fehler in der Tabelle wird es nie eine Gelegenheit geben, sie zu betrachten. Sicher, ich hätte die Daten von einer Ressource oder dergleichen erhalten können, aber das würde die Verwendung des Compilers ausschließen, um das Lesen zu vereinfachen.

4
Loren Pechtel

Ich würde sagen, es ist ein "Code-Geruch".

Anti-Patterns sind im Allgemeinen grundlegende strukturelle Probleme in einer Software, während Regionen für sich genommen nur ein unangenehmes Verhalten in einem Editor verursachen. Die Verwendung von Regionen ist eigentlich nicht von Natur aus schlecht, aber eine häufige Verwendung, insbesondere zum Verbergen von Codestücken, kann darauf hinweisen, dass an anderer Stelle andere, unabhängige und größere Probleme auftreten.

3
whatsisname

Bei einem kürzlich durchgeführten Projekt gab es eine 1700-Linien-Methode, in die mehrere Regionen eingebettet waren. Das Interessante ist, dass die Regionen unterschiedliche Aktionen abgegrenzt haben, die innerhalb der Methode durchgeführt wurden. Ich konnte eine Refactor -> Extraktionsmethode für jede der Regionen durchführen, ohne die Funktionalität des Codes zu beeinträchtigen.

Im Allgemeinen sind Bereiche zum Ausblenden des Kesselplattencodes nützlich. Ich würde davon abraten, Regionen zum Ausblenden von Eigenschaften, Feldern und dergleichen zu verwenden, da dies wahrscheinlich ein Zeichen dafür ist, dass die Klasse weiter unterteilt werden sollte, wenn sie bei der Arbeit in der Klasse zu unhandlich sind. Wenn Sie jedoch eine Region in eine Methode einfügen, ist es in der Regel besser, eine andere Methode zu extrahieren, die erklärt, was passiert, als diesen Block in eine Region zu verpacken.

3
Michael Brown

Können Regionen in Code von guter Qualität verwendet werden? Wahrscheinlich. Ich wette, das sind sie in vielen Fällen. Meine persönliche Erfahrung macht mich jedoch sehr misstrauisch - ich habe Regionen gesehen, die fast ausschließlich missbraucht wurden. Ich würde sagen, dass ich erschöpft bin, aber immer noch optimistisch.

Ich kann den bisher verwendeten Regionscode grob in drei Kategorien einteilen:

  • Schlecht faktorisierter Code: Der meiste Code, den ich gesehen habe, verwendet Regionen als Factoring-Tool für arme Männer. Beispielsweise kann eine Klasse, die so weit gewachsen ist, dass es sinnvoll ist, sie für verschiedene Zwecke zu spezialisieren, stattdessen in separate Regionen aufgeteilt werden, eine für jeden Zweck.

  • Code, der mit den falschen Bibliotheken und manchmal mit der falschen Sprache für die Problemdomäne geschrieben wurde Wenn ein Programmierer nicht die richtigen Bibliotheken für die Problemdomäne verwendet, wird der Code oft unglaublich ausführlich - mit vielen kleinen Hilfsfunktionen die wirklich nicht gehören (sie gehören wahrscheinlich in ihre eigene Bibliothek).

  • Code, der von Studenten oder Absolventen geschrieben wurde. Einige Programme und Kurse scheinen zu versuchen, Studenten die Nutzung von Regionen für alle möglichen seltsamen Zwecke zu vermitteln. Sie werden sehen, dass Regionen den Quellcode so weit verunreinigen, dass das Verhältnis von Regions-Tags zu Codezeilen im Bereich von 1: 5 oder schlechter liegt.

3
blueberryfields

Ich benutze Regionen nur für eine Sache (zumindest kann ich mir keine anderen Orte vorstellen, an denen ich sie benutze): um Unit-Tests für eine Methode zu gruppieren.

Normalerweise habe ich eine Testklasse pro Klasse und gruppiere dann die Komponententests für jede Methode, indem ich Regionen verwende, die den Namen der Methode haben. Ich bin mir nicht sicher, ob das ein Codegeruch ist oder so, aber da die Grundidee ist, dass Unit-Tests nicht geändert werden müssen, es sei denn, sie brechen, weil sich etwas im Code geändert hat, ist es für mich einfacher, alle Tests für eine bestimmte Methode zu finden ziemlich schnell.

Ich habe in der Vergangenheit möglicherweise Regionen zum Organisieren von Code verwendet, kann mich aber nicht erinnern, wann ich es das letzte Mal getan habe. Ich halte mich jedoch in Unit-Test-Klassen an meine Regionen.

3
Anne Schuessler

Ich glaube, das ist ein Anti-Muster und ehrlich gesagt denke, sie sollten beseitigt werden. Aber wenn Sie sich in der unglücklichen Situation befinden, an einem Ort zu arbeiten, an dem es sich um ein Standard-Visual Studio handelt, bietet Visual Studio ein großartiges Tool, um die Menge zu minimieren, die Sie jedes Mal erbrechen möchten, wenn Sie eine Region sehen Ich hasse #Regionen

Dieses Plugin maximiert die Schriftgröße der wirklich kleinen Regionen. Sie werden auch erweitert, sodass Sie nicht Strg + M + L drücken müssen, um alle Regionen zu öffnen. Es behebt diese Form von Codekrebs nicht, macht es aber erträglich.

2
DeadlyChambers

Regionen waren eine raffinierte Organisationsidee, berücksichtigten jedoch nicht die Tendenz einiger Entwickler, alles überkategorisieren zu wollen, und waren nach den meisten modernen Praktiken im Allgemeinen unnötig OOP Praktiken ... sie sind ein "Geruch" in dem Sinne, dass ihre Verwendung häufig darauf hinweist, dass Ihre Klasse/Methode viel zu groß ist und überarbeitet werden sollte, da Sie wahrscheinlich gegen das "S" von SOLID Prinzipien ... verstoßen ... aber wie jede andere) riechen, es bedeutet nicht unbedingt , dass etwas schlecht läuft.

Regionen dienen eher dem Funktionscode als dem objektorientierten Code IMO, bei dem Sie über lange Funktionen für sequentielle Daten verfügen, deren Aufteilung sinnvoll ist. Es gab jedoch Zeiten, in denen ich sie persönlich in c # verwendet habe, und sie fast immer Konzentrieren Sie sich auf Code, den Sie nicht sehen müssen/wollen. Für mich waren dies normalerweise rohe SQL-String-Konstanten in der Codebasis, die für NPoco oder seine Varianten verwendet wurde. Sofern es Ihnen nicht wirklich wichtig ist, wie die Daten das POCO-Objekt über Ihr ORM ausfüllen, waren diese völlig sinnlos anzusehen ... und wenn es Sie interessierte, hey, erweitern Sie einfach die Region und BAM! Über 150 Zeilen einer komplizierten SQL-Abfrage für Ihr Sehvergnügen.

0
Jeremy Holovacs

Ich verwende Regionen, um jede Kombination aus Sichtbarkeit und Elementtyp zu enthalten. Alle privaten Funktionen gehen also in eine Region usw.

Der Grund, warum ich das tue, ist nicht, dass ich Code zusammenfalten kann. Dies liegt daran, dass ich meinen Editor als Skript erstellt habe, damit ich beispielsweise einen Verweis auf einen Proxy einfügen kann:

#region "private_static_members"
 /// <summary>
 /// cache for LauncherProxy
 /// </summary>
private static LauncherProxy _launcherProxy;
#endregion

#region "protected_const_properties"
protected LauncherProxy LauncherProxy{
  get{
    if(_launcherProxy==null) {
      if (!God.Iam.HasProxy(LauncherProxy.NAME)) {
        God.Iam.RegisterProxy(new LauncherProxy());
      }
      _launcherProxy=God.Iam.Proxy(LauncherProxy.NAME) as LauncherProxy;
    }
    return _launcherProxy;
  }
}
#endregion

in den Code und lassen Sie jedes Teil ordentlich in die richtige Region stecken.

In diesem Fall würde das Makro mein Projekt analysieren, mir eine Liste von Proxys geben und den Code für den gewünschten einfügen. Mein Cursor bewegt sich nicht einmal.

Zu Beginn des Lernens von C # hatte ich über die Verwendung von Regionen nachgedacht, um Gemeinsamkeiten zusammenzuhalten, aber das ist ein Erfolg und Misserfolg, da es nicht immer eine Eins-zu-Eins-Beziehung ist. Wer möchte sich über ein Mitglied ärgern, das von zwei Regionen verwendet wird, oder sogar anfangen, Dinge unter diesen Bedingungen aufzubrechen?.

Die einzige andere Art der Trennung sind Methoden. Ich werde Methoden in Befehle, Funktionen und Handler aufteilen, damit ich eine Region für öffentliche, private usw. Befehle usw. habe.

Dies gibt mir Granularität, aber es ist konsistent, eindeutig Granularität, auf die ich mich verlassen kann.

0
Mark

Regionen sind Präprozessorausdrücke - mit anderen Worten, sie werden wie Kommentare behandelt und vom Compiler grundsätzlich ignoriert. Sie sind ein rein visuelles Werkzeug, das in Visual Studio verwendet wird. Daher ist #region nicht wirklich ein Codegeruch, weil es einfach kein Code ist. Der Code-Geruch ist eher die 800-Zeilen-Methode, in die viele verschiedene Verantwortlichkeiten eingebettet sind. Wenn Sie also 10 Regionen in einer Methode sehen, wird sie wahrscheinlich verwendet, um einen Code-Geruch zu verbergen. Trotzdem habe ich gesehen, dass sie äußerst effektiv eingesetzt wurden, um eine Klasse für das Auge angenehmer und navigierbarer zu machen - auch in einer sehr gut geschriebenen und strukturierten Klasse!

0
BKSpurgeon