2010-06-18 18 views
21

Ich war zu aufgeregt, als Objektinitialisierer in C# erschien.C# Objektinitialisierer Komplexität. Best Practice

MyClass a = new MyClass(); 
a.Field1 = Value1; 
a.Field2 = Value2; 

kürzer neu geschrieben werden:

MyClass a = new MyClass { Field1 = Value1, Field2 = Value2 } 

Objektinitialisierer Code offensichtlicher, aber wenn Eigenschaften Dutzend kommen Nummer und einige der Zuordnung beschäftigt sich mit Nullable-Werte ist es schwer zu debuggen, wo die „NULL-Verweis Fehler "ist. Studio zeigt den gesamten Objektinitialisierer als Fehlerpunkt an.

Heutzutage verwende ich Objektinitialisierer für einfache Zuordnung nur für fehlerfreie Eigenschaften.

Wie verwenden Sie Objektinitialisierer für die komplexe Zuweisung oder es ist eine schlechte Übung, Dutzende von Aufgaben überhaupt zu verwenden?

Vielen Dank im Voraus!

Antwort

17

Nun, mein Hauptbeef mit Objektinitialisatoren ist, dass sie einen veränderlichen Typ benötigen, um damit zu beginnen: wo möglich, bevorzuge ich unveränderliche Typen. Wenn ein Objektinitialisierer arbeitet (z. B. für UI-Steuerelemente), neige ich dazu, sie zu verwenden.

Ich würde möglicherweise zweimal überlegen, ob die Werte für die Zuordnungen waren besonders kompliziert zu berechnen - insbesondere müssen Sie in der Lage sein, den Wert in einem einzigen Ausdruck, und das kann am Ende weniger lesbar als Computing es über mehrere Aussagen ... aber das ist relativ selten in Situationen, in denen dies möglich ist, mit zu beginnen.

Ich kann nicht sagen, dass ich irgendwelche Probleme mit Ausnahmen während Eigenschaftenzuweisungen mit Objektinitialisierer hatte - es ist einfach nicht etwas, das für mich aufkommt. Wenn es so wäre, würde ich wahrscheinlich versuchen, einen fehlerhaften Komponententest zu schreiben, an welchem ​​Punkt der Code normalerweise ohne den Debugger sowieso einfach zu reparieren ist.

Offensichtlich ist Moderation immer eine gute Sache - ich schlage nicht vor, dies auf die Spitze zu treiben ... aber wenn Sie ein Dutzend Eigenschaften festlegen, wäre die Verwendung eines Objektinitialisierers für mich nicht so wichtig ein Dutzend Eigenschaften haben, um mit zu beginnen. Sind irgendwelche dieser Dutzend Eigenschaften verbunden? Sollten diese irgendwie zusammen gekapselt sein? (In einigen Fällen ist das gut - wieder, vor allem mit UI-Steuerelementen - aber oft ist es nicht.)

+1

Normalerweise habe ich solchen Code bei Geschäftsobjekten. Eigenschaften werden von der Benutzeroberfläche aus ausgefüllt oder stammen aus verschiedenen Tabellen. –

+0

Ich mag Objektinitialisierungen in einem DAO nicht, weil Sie das Feld normalerweise von einem Lesegerät erhalten und es oft zu Problemen kommen kann. Sie erhalten keine Compiler-Sicherheit. In diesem Fall kann man sich mit einem Komponententest nicht wirklich schützen, weil es zu einem Integrationstest wird. Entitäten außerhalb der DB haben typischerweise ein paar mit ihnen assoziierte Felder. Wenn die Zuweisungen jedoch trivial sind, verwende ich einen Objektinitialisierer. – uriDium

0

Ich verwende es nie in Code, der in Entwicklung ist, weil wie Sie darauf hinweisen, ist es schwieriger zu debuggen.

Code, der gut getestet wurde, kann den Code lesbarer machen, obwohl man argumentieren könnte, dass man nicht mit gut getestetem und funktionierendem Code herumhantieren sollte, nur um das Lesen zu erleichtern.

Denken Sie daran, Objekt Initialisierer wurden in erster Linie in die Sprache eingeführt, um die Linq-Syntax legal zu machen. Das bedeutet nicht, dass es breiter genutzt werden sollte.

Mit dem gesagt, wenn Sie eine Reihe von Eigenschaften für eine Reihe von Steuerelementen festlegen, kann die Einrückung allein es viel einfacher machen, einen schnellen Überblick darüber zu erhalten, wo bestimmte Steuerelemente ihre Eigenschaften festgelegt haben.

+0

"Sie sollten nicht mit gut getestetem und funktionierendem Code herumhantieren, nur um es einfacher zu lesen" - die Verwendung eines Objektinitialisierers ist eines der sichersten Refactorings, die es gibt. Sind Sie kein Fan von Refactoring im Allgemeinen? –

+0

Ja Jon, ich stimme Ihnen in diesem Punkt sehr zu. Refactor wo es Sinn macht. Wenn es Leistungssteigerungen geben soll und wenn Code sicherer und robuster gemacht werden kann. Sicherlich ist es eine Best-Practice, Typen zu ändern, die du schreiben kannst, wie du in deiner Antwort erwähnt hast. Aber Refactoring zur Verwendung von Objektinitialisierern ist nicht oft ein guter Nutzen für die Zeit von irgendjemandem. –

+0

Sie könnten LINQ ohne Objektinitialisierer (sogar anonyme Typen, weil ich denke, dass Sie das meinen) perfekt verwenden, obwohl es viel schwerer zu lesen wäre. – ErikHeemskerk

3

Wenn Sie Ihre Anwendung debuggen, sollten Sie in den meisten Fällen immer noch in der Lage sein, die Debugging-Tools von VS zu verwenden, um zu ermitteln, welche Zuweisung die Nullreferenz verursacht.

Wenn Sie jedoch die Zuordnung über mehrere Zeilen, ich denke, VS auf die richtige Linie zeigen, wenn eine Ausnahme ausgelöst wird:

MyClass a = new MyClass { 
        Field1 = Value1, 
        Field2 = Value2 }; 

Hinweis: Ich habe das selbst nicht tun, so sanft sein über meinen (möglicherweise) entsetzlichen, linienbrechenden Stil.

+1

Nein, nein :) Mein Studio markieren alle Zeilen der Objektinitialisierer wenn Fehler kommen und ich weiß nicht, welche Eigenschaft ein Problem hat –

+0

Ich sehe. Dann denke ich für Debugging-Zwecke ist es eine Art von Belastung, es sei denn, Sie wollen Maus über jeden Ausdruck, den Sie den Feldern zuweisen und sehen, welcher Null ist. – ErikHeemskerk