c # Konstruktoren vs Auto-Eigenschaften und Objektinitialisierer

8

Ich habe die automatischen Eigenschaften sehr oft verwendet, aber ich bin mehr und mehr davon entfernt, Klassen mit schreibgeschützten Stützfeldern einzurichten, die im Konstruktor initialisiert wurden. Ich entferne alle Setter und füge nur die Rückseite hinzu, wenn die Eigenschaft eindeutig einen Setter benötigt.

Ich finde, dass dies meine Klassen robuster und eleganter macht und ich trete dafür, dass ich das nicht früher mache.

Ich finde, Konstruktoren werden im Allgemeinen in c # -Codebeispielen sehr selten verwendet und ich denke, dass Auto-Eigenschaften und Objektinitialisierer ein großer Teil davon sind. Daher ist meine Frage, warum das c # -Team solche Features pusht und sich nicht mehr darauf konzentriert Features, die Best Practices vorantreiben. Im Allgemeinen denke ich, dass es zu einfach ist, schlechten Code zu schreiben, und glaube, dass mehr getan werden könnte, indem man den Programmierern hilft, einen guten Code zu schreiben.

    
terjetyl 03.09.2010, 23:02
quelle

3 Antworten

13

Aus Gesprächen glaube ich, dass das C # -Team versteht, dass es leichter war, änderbare Typen zu schreiben, während es für unveränderliche Typen keinen ähnlichen Vorteil bietet. Es ist nicht so, dass sie die Unveränderlichkeit im Laufe der Zeit schwieriger gemacht haben - sie haben es einfach nicht einfacher gemacht ... außer anonymen Typen, die unveränderlich sind, aber verschiedene andere Nachteile haben. Ich würde natürlich nicht wollen, dass automatische Eigenschaften weggenommen werden - wo sie angebracht sind, sind sie wirklich nützlich. Ich würde einfach gerne das Äquivalent für schreibgeschützte Eigenschaften haben (so dass sie nur im Konstruktor gesetzt werden können).

Ich habe festgestellt, dass die benannten Argumente und optionalen Parameter von C # 4 es einfacher gemacht haben, Instanzen des unveränderlichen Typs zu konstruieren - Sie können trotzdem viele der Vorteile von Objektinitialisierern erhalten, ohne die Nachteile der Wandlungsfähigkeit. Geben Sie einfach Standardwerte für Aspekte Ihres Typs an, die wirklich optional sind, lassen Sie den Rest als obligatorische Konstruktorparameter, und der Aufrufer kann tun, was er will - benannte Argumente, um Klarheit zu schaffen.

Sammlungsinitialisierer sind leider eine härtere Nuss zum Knacken. Ich würde gerne "verkettete" Initialisierer sehen, die mit unveränderbaren Sammlungen arbeiten könnten, so dass der Compiler Aufrufe von Add , die zusammen verkettet wurden, statt wiederholt Plus für dieselbe Instanz aufrufen würde:

%Vor%

würde gehen zu:

%Vor%

Natürlich wäre es schön, mehr unveränderbare Sammlungen im Framework zu haben, mit denen man anfangen kann:)

Nichts davon hilft natürlich auf der Auto-Props-Seite. Ich muss zugeben, dass ich in letzter Zeit eine gewisse Anzahl betrogen habe, indem ich die Unveränderlichkeit mit privaten Settern vorgetäuscht habe:

%Vor%

Es macht mich zwar schmutzig, aber ich mache es nicht wirklich unveränderlich, wenn das meine wahre Absicht ist.

Grundsätzlich sage ich, dass ich deinen Schmerz fühle - und ich bin mir ziemlich sicher, dass das C # -Team tut. Denken Sie daran, dass sie nur begrenzte Ressourcen haben, und das Entwerfen einer Sprache ist hart.

Vielleicht finden Sie die Videos von NDC 2010 interessant - es gibt eine großartige Podiumsdiskussion mit Eric Lippert, Mads Torgersen, Neal Gafter (und ich), und meine Vorschläge für C # 5 sind in einem anderen Video.

    
Jon Skeet 03.09.2010, 23:06
quelle
1
  

Ich entferne alle Setter und füge nur die Rückseite hinzu, wenn die Eigenschaft eindeutig einen Setter benötigt.   Ich finde das macht meine Klassen robuster und eleganter OO-weise

Ich stimme Ihnen vollkommen zu. Ich sah mich mit Legacy-Code konfrontiert, in dem viele Objektinitialisierer für einige Klassenhierarchien verwendet werden. Ich musste einige Eigenschaften hinzufügen, und dann bekam ich Kopfschmerzen, wenn ich alle Orte fand, an denen Klasseninstanzen konstruiert wurden. Das erste Mal, dass ich mich beworben habe. Und jetzt muss ich eine weitere Eigenschaft hinzufügen. Das ist verrückt!

Um die Verwendung von Objektinitialisierern einzuschränken, habe ich den parameterlosen Konstruktor gelöscht.

    
Vadim Sukhorukov 26.07.2012 08:56
quelle
0
  

Ich finde, Konstruktoren werden in c # -Codebeispielen generell sehr selten verwendet und ich denke, dass Auto-Eigenschaften und Objektinitialisierer ein großer Teil davon sind.

Wenn Ihr Objekt viele Eigenschaften hat, wollen Sie diese natürlich nicht alle vom Konstruktor initialisieren. Mehr als, sagen wir, 4 oder 5 Parameter zu übergeben, ist ziemlich schlecht für die Lesbarkeit (obwohl Intellisense es einfach macht zu schreiben). Wenn Sie nur einige Eigenschaften initialisieren und den Standardwert für andere Eigenschaften verwenden möchten, benötigen Sie entweder viele Konstruktorüberladungen, oder Sie müssen diese Standardwerte explizit an den Konstruktor übergeben.

In solchen Fällen sind Objektinitialisierer sehr nützlich, solange die Eigenschaften nicht schreibgeschützt sind (aber, wie Jon betonte, optionale Parameter in C # 4 sind eine gute Alternative)

  

Warum pusht das c # Team solche Features und konzentriert sich nicht mehr auf die Bereitstellung von Features, die Best Practices vorantreiben

Ich denke, dass Objektinitialisierer eingeführt wurden, weil sie für Linq notwendig waren: Sie konnten keine anonymen Typen ohne sie erstellen. Was Auto-Eigenschaften betrifft, sind sie weniger wichtig, aber es war wahrscheinlich einfach zu implementieren und es kann eine echte Zeitersparnis für Eigenschaften sein, die nichts weiter tun, als ein Feld zu kapseln.

    
Thomas Levesque 04.09.2010 00:39
quelle