#region == Failcode
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:
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:
Mir geht es dann meisten so, dass ich ja trotzdem den Code sehen will. Also mal reinklicken:
Spannend. Nagut… was ist denn bei Y los?
Alle guten Dinge sind drei. Was steht hinter Z?
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:
- Regions == Evil
- Do you #region?
- C# Regions Considered Harmful
- #Regions, or "How to disorganize your code"







Daniel
9. September 2010
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…
Björn
9. September 2010
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.
Hendrik Lösch
9. September 2010
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.
Viktor
9. September 2010
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.
Martin
9. September 2010
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.
Thomas
9. September 2010
“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
Lennart
10. September 2010
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.
Jürgen Gutsch
13. September 2010
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
Omer Rauchwerger
14. September 2010
@Lennart – you can use Regionerate to order your classes without regions.