#region == Failcode

image

Das Thema ist wahrscheinlich schon ewig alt, aber durch einen übermotivierten Kollegen, der überall “regions” in den Code reingeballert hat, kam das Thema bei uns wieder auf: Sind #regions gut oder schlecht? Für alle die nicht wissen worum es geht: #region auf MSDN

 

 

Schauen wir uns mal ein Beispiel an…

Ich mach die User.cs auf und sehe das:

image

Wobei “…” für diverse andere Sachen noch stehen kann.

Der erste Eindruck:

Ist ja aufgeräumt.

Aber jetzt mal ehrlich…

Mich interessiert der Code, nicht irgendwelche Blöcke. Mit #region versteckt man den Code doch nur. Wenn ich in die User.cs reinschaue, möchte ich auch den Code auf den ersten Blick sehen. Ja, es gibt ein Tastenkürzel um alles aufzublenden. Aber wozu überhaupt diese #region Blöcke?

Code Smell

Häufig habe ich #regions in Klassen gefunden, welche etliche hundert Zeilen lang waren. Durch die #regions sollte der Code etwas strukturierter werden.

Man schaut z.B. in eine Methode und erblickt folgendes:

image

Mir geht es dann meisten so, dass ich ja trotzdem den Code sehen will. Also mal reinklicken:

image

Spannend. Nagut… was ist denn bei Y los?

image

Alle guten Dinge sind drei. Was steht hinter Z?

image

Super, oder? Der Code ist natürlich hier in meinem Beispiel Blödsinn, aber hinter X, Y und Z können sich kilometerlange Codeblöcke verstecken.

Warum ich #regions für missverstandenen Ordnungssinn halte:

IMHO bringen sie keine wirklichen Vorteile mit sich. Auf dem ersten Blick sieht es nett aus, aber am Ende könnte man auch folgende Schluss daraus ziehen:

Die Klasse hat zu viele Aufgaben und muss deswegen optisch etwas aufgehübscht werden. Besser: Aufsplitten! Und damit meine ich nicht in “Partial Classes”, sondern in getrennte Funktionseinheiten.

Interface Implementierungen

Ein anderes Beispiel: Visual Studio macht Interface Implementierungen grundsätzlich in #regions. Schön finde ich es nicht (und man kann es auch abstellen ;) ). Trägt es wirklich zur Strukturierung bei? IMHO kaschiert das #regions, für einen besseren Überblick gibt es spätestens seit VS2010 auch andere nette Tools – da brauch ich keine #regions.

Zudem…

Wenn man “On-the-fly” (z.B. in TDD Manier) Code erstellt, dann packt Visual Studio den Code auch irgendwo hin. Damit ist das System mit den #regions auch zum Scheitern verurteilt.

Weitere Anti-#region Posts

In diesem Post ist auch ähnlich beschrieben, warum er #regions nicht mag. Hier noch weitere:

Wenn dir der Blogpost gefallen hat, dann hinterlasse doch einen Kommentar. Wenn du auf dem Laufenden bleiben willst, abonniere unseren RSS Feed oder folge uns auf Twitter.

About the author

Written by

Hi, ich bin Robert Mühsig und bin Webentwickler und beschäftige mich mit Web-Frameworks auf dem Microsoft Web Stack und scheue mich auch nicht vor Javascript. Der Blog begann als "Problemsammelstelle und Lösungshilfe" und seitdem schreibe ich hier alles auf. Seit 2008 bin ich Microsoft MVP für ASP.NET. Treffen kann man mich online via Twitter (@robert0muehsig) oder hier.

11 Responses

  1. Ich stimme dem uneingeschränkt zu!!!

    Wer regions benötigt, verletzt typischerweise andere etablierte Grundsatzregeln beim Klassendesign. Zudem ist das Tooling heutzutage so gut geworden, dass man zig bessere Möglichkeiten hat, die Code Struktur aufzulisten, zu filtern bzw. (schöner) zu visualisieren.

    In unseren Coding Guidelines sind regions schon lange verpönt…

    Reply
  2. Das Beispiel oben ist schon echt heftig.

    Ich persönlich nutze #region nur, um gleiche Sachen zusammen zu fassen.. also #region Public Properties oder so ähnlich (kommt auch immer auf die größe an).

    Der Vorteil für mich ist hierbei, dass ich sie bei einander habe und bei Bedarf mal eben ausblenden kann. Letztens habe ich auch eine Erweiterung für VS2010 gesehen, mit denen IF-Bereiche eingeklappt werden können, leider weiß ich grad ihren Namen nicht, werde ich noch mal nachreichen, wenn es jemanden interessiert.

    Reply
  3. Regions innerhalb von Methoden halte ich auch für unsinnig. Hier ist es ein eindeutiges Zeichen das mal refaktorisiert werden sollte. Dennoch habe ich Regions auf Klassenebene lieben gelernt. Vorallem dank Region Rate.

    Eine Klasse in der alle Properties, Fields, Konstruktoren und Methoden gruppiert und alphabetisch sortiert sind hat für mich eine gewisse Ästetik. Auch bei Unittests kann ich auf diese Weise die üblichen Initialisierungen ausblenden oder die Tests sinnvoll gruppieren und Regionen sind dabei unersetzlich.

    Das man mit ihnen viel Mist machen kann, keine Frage. Das man mit ReSharper oder der stink normalen Suche schneller zum Ziel findet, geschenkt. Aber mir helfen sie einfach das übliche und wiederkehrende (IDisposable methoden, ToString, oder auch Initialisierungsmethoden) vom unüblichen (tatsächlich zu realisierende Funktion) zu trennen. Auch das verstehe ich unter einem gewissen Smell.

    Also bitte die Regions nicht verteufeln weil einige damit eine Menge Mist bauen können. Sonst gehören Pointer in C++ (ich weiß der Vergleich ist übertrieben), unsafed Code und lambda Expressions auf dem gleichen Scheiterhaufen verbrannt.

    Reply
  4. Wir haben in unseren Guidlines regions definiert die Methoden / Properties / Felder gruppieren sollen. Auf der nächst höheren Ebene wird eine Gruppier nach Zugriffsverifizierer gemacht (public / protected / private). Danach gibt es noch eine Ebene auf Instanz und Klassen Member.
    Alle sind “Optional” das bedeutet wenn es keine protected felder gibt so wird auch keine protected region angelegt.
    Vorteile davon sind zum einen das Review geht einfacher. Da man beim Review sich die öffentlichen Schnitstellen sich zuerst anschaut und sich danach “runter” in die Privaten Methoden durcharbeitet.

    Erweiterungen an einer Klasse sind ebenfalls einfacher da man nicht nach den ganzen Feld oder Event Deklarationen suchen braucht.

    Das Implementieren von Methoden ebenfalls da man sich auf seinen kleinen Bereich konzentrieren kann und nicht abgelengt wird von anderen Einheiten der Klasse (DepencyProperties, Events, …).

    Ich behaupte mal das die Klassen nicht überdimensioniert sind. Dafür haben wir ebenfalls klare Regeln die auf bewährten Prinzipien aufsetzen (SoC) oder aber welche von uns definierten (Methode nie länger als eine Bildschirmseite).

    Ich gebe dir recht das dein Beispiel wirklich genau ausdrückt das regions von einigen nicht verstanden worden sind. Ist es soweit gekommen das man in einer Methode mit regions arbeitet so hat man was falsch gemacht.

    Gruß Viktor.

    Reply
  5. Ich selbst verwende Regions auch nicht mehr freiwillig.

    Wenn ich sie verwende, dann weil irgendwelche Coding Guidelines es vorschreiben. Diese sind dann meist noch aus der Zeit von VS 2003 als das Tooling noch recht rudimentär war und Regions die Navigation im Code unterstützen sollten.

    Deswegen sind Regions selbst nicht böse. Wie bei vielen Dingen, ist es lediglich die falsche oder überholte Verwendung, die Regions böse macht.

    Dein Beispiel ist schon etwas krass, auch wenn es wie ich glaube aus dem wahren Leben gegriffen ist, denn solchen Code hab ich auch schon gesehen – mit ähnlichen Gedanken wie von dir geäußert.

    Reply
  6. “Mich interessiert der Code, nicht irgendwelche Blöcke.”

    Ja. Und nein. Regions in Produktivcode halte ich (inzwischen) auch für ein deutliches Zeichen von Code Smell. Wer die da braucht um Übersicht zu schaffen, sollte mal ReSharper anwerfen und mit dem Refactoring beginnen.

    Aber: ich nutze sie in meinen Testklassen. Ich schreibe für jeden Testcase eine eigene Testklasse und lasse mir beim Erzeugen aus der Spezifikation gleich noch die passende Region mit generieren. Das finde ich ok, vor allem da ich nicht glaube, dass ein Aufgliedern in einzelne Files die Sache besser macht (vor allem nicht bei dem verwendeten Naming).

    Beispiel: http://twitpic.com/2mnfqv

    Reply
  7. Ich halte die Einteilung von Methoden, Eigenschaften und Feldern in Regions nach ihren Zugriffsmodifizierern auch nicht für sinnvoll. Man erfreut sich zwar zunächst über die Ordnung die man geschaffen hat, das Öffnen und Schließen von Regions empfinde ich aber eher als störend. Am besten erreicht man seine Methoden über den Solution Navigator der Productivity Power Tools finde ich. Eine Sortierung nach Zugriffsmodifizierern sollte aber trotzdem vorhanden sein. Kennt ihr gute Erweiterungen die sowas automatisch machen? Ich kennen nur Regionerate, wo zwar sortiert, aber auch alles in Regions eingeteilt wird.

    Reply
  8. Wenn man seine Methoden und Eigenschaften so hintereinander schreibt, wie es Uncle Bob vorschlägt, funktionieren Regions die Zugriffsmodifizierer gruppieren nicht mehr.
    Uncle Bob die Reihenfolge der Methoden von deren Aufruf abhängig zu machen: (public) Methode1 ruft (private) Methoden11 und (private) Methode12 in dieser reihenfolge auf. (private) Methode11 ruft (private) Methode111 auf. (public) Methode2 nutzt ebenfalle Methode11. Daraus ergibt sich folgende Reihenfolge:
    Methode1
    Methode11
    Methode111
    Methode12
    Methode2

    Vorteile? Weniger herumscrollen nötig, da Der Code in einem Logischem Fluss gelesen werden kann.

    Gruppierung mit Regions nach Thema innerhalb einer Klasse macht ebenfalls keinen Sinn. Wenn Thematisch gruppiert werden kann man auch die Klasse aufteilen.

    Gruppierung nach Member-Typ würde als einigste Variante weiter funktionieren. Allerdings sollte man sich auch hier fragen, ob es wirklich nötig ist. Wenn die Klasse zu groß ist, sollte man diese eventuelle Aufteilen. Wenn der Code sonst zu unübersichtlich ist, sollte man diesen auf jeden Fall refaktorieren. Ist der Code sauber, machen Regions wiederum keinen Sinn mehr.

    Ich selber verwende auch keine Regions mehr. Den einzigen Nutzen ist IMHO, unsauberen Code sauber asusehen zu lassen ;-)

    Viele Grüße
    Jürgen

    Reply
  9. @Lennart – you can use Regionerate to order your classes without regions.

    Reply

Comment on this post

Letzte Posts

  • image.png
    Source Code veröffentlichen – aber bitte mit Lizenz

    Seit es den Blog gibt wird auch meist der gesamte Demo Source Code mit veröffentlicht. Das Ganze hatte ich am Anfang noch als .zip verteilt, später lag es mal auf Google Code und nun liegen alle Samples und sonstige Sachen auf GitHub. Beim letzten User Group Treffen in Zürich mit dem Titel “Open Source: Get […]

  • Fix: Cannot convert from ‘CConnectProxy::_ComMapClass *’ to ‘AddInDesignerObjects::IDTExtensibility2 *’

    Mal einen etwas esoterischer Blogpost, welcher auftaucht wenn man zu viel mit Office Addins rumspielt. Der Fehler passiert beim Bauen von C++ Projekten, welchen diesen Typ benötigen. Lösung (auf 64bit Systemen): C:\Program Files (x86)\Common Files\DESIGNER>regsvr32 MSADDNDR.DLL And Rebuild. Meine lieben Kollegen hatte mir dies schon mehrfach gesagt, allerdings hatte ich es immer wieder vergessen Das […]

  • Gegen das Gesetz verstoßen: X Jahre Haft. Gegen die Terms of Use verstoßen: Bann auf Lebenszeit. Danke Google & co.

    Bei fast allen Diensten die man im Internet nutzen kann muss man den “Terms of use” zustimmen. Völlig logisch dass da natürlich drin steht was erlaubt und was nicht. Wenn man gegen diese Regelungen verstößt hat das Unternehmen natürlich das Recht etwas dagegen zu unternehmen. In der heutigen Welt beherrschen einige wenige Unternehmen die digitale […]

  • image.png
    RSS Feed samt Kommentaranzahl und andere nicht Standard Elemente mit dem SyndicationFeed auslesen

    Jetzt mal ein Blogpost ohne ein fancy NuGet Package: Seit .NET 3.5 gibt es die SyndicationFeed Klasse. Eine schon etwas ältere API, reicht aber aus um Atom bzw. RSS Feeds zu lesen. In diversen RSS Feeds gibt es aber Erweiterungen, welche man natürlich auch auslesen möchte. So gibt WordPress z.B. auch die Anzahl der geposteten […]

  • image.png
    ASP.NET Bundling & Fontawesome

    Vor einer halben Ewigkeit hatte ich mal geschrieben wie man Fontawesome in ASP.NET nutzen kann. Aufgrund des Alters des Post und einem Kommentar ob man denn Fontawesome auch in das ASP.NET Bundling Framework integrieren kann möchte ich nur ein kurzes Update schreiben. TL;DR: NuGet Package “Fontawesome” runterladen und Pfad in der Bundleconfig angeben. Kurze Schritte […]

Amazon Shop

Facebook