2010-09-03 19 views
8

Ich habe Auto-Eigenschaften viel verwendet, aber ich habe mehr und mehr weg von diesem Einrichten von Klassen mit Readonly Backing-Felder im Konstruktor initialisiert. Ich entferne alle Setter und füge nur die Rückseite hinzu, wenn die Eigenschaft eindeutig einen Setter benötigt.C# Konstruktoren vs Auto-Eigenschaften und Objektinitialisierer

Ich finde dies macht meine Klassen robuster und eleganter OO weise und ich trete mich selbst dafür, dies nicht früher zu tun.

Ich finde Konstruktoren werden in C# -Codebeispielen sehr selten verwendet und ich denke, Auto-Eigenschaften und Objektinitialisierer sind ein großer Teil davon, also meine Frage ist, warum das C# -Team Funktionen wie folgt und nicht mehr konzentriert Funktionen bereitstellen, die Best Practices stärker vorantreiben. Generell denke ich, es ist zu einfach schreiben schlechten Code und glauben, dass mehr getan werden könnte, helfende Programmierer schreiben guten Code

+0

Nicht alle Typen müssen unveränderbar sein. Es ist durchaus üblich (und heilsam), einen veränderbaren Typ in einem Konstruktor zu verwenden und ihn dann in ein privates Element zu kopieren. Dann wird es vor Änderungen durch externen Code geschützt (vorausgesetzt, dass es dasselbe für mutable Abhängigkeiten tut). Dies gilt insbesondere für reine Altdatenobjekte. –

Antwort

13

Von Gesprächen, ich glaube, das C# -Team versteht, dass sie es leichter gemacht haben, veränderliche Typen zu schreiben, während nicht ähnliche Vorteile für unveränderliche Arten. 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 nur gerne das Äquivalent für schreibgeschützte Eigenschaften haben (so dass sie nur im Konstruktor gesetzt werden können).

Ich habe festgestellt, dass C# 4 benannte Argumente und optionale Parameter es einfacher gemacht haben, unveränderliche Art Instanzen zu konstruieren - Sie können immer noch 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 - mit benannten Argumenten, um Klarheit zu schaffen.

Kollektionsinitialisierer sind leider eine härtere Nuss zum Knacken. Ich möchte „gekettet“ initializers sehen, die mit unveränderlichen Sammlungen arbeiten konnte, so dass anstatt immer wieder Add auf der gleichen Instanz aufrufen, könnte der Compiler Anrufe Plus schaffen, die miteinander verkettet:

ImmutableList<string> x = new ImmutableList<string> { "a", "b", "c" }; 

gehen würde, um :

ImmutableList<string> x = new ImmutableList<string>().Plus("a") 
                .Plus("b") 
                .Plus"(c"); 

natürlich wäre es schön, mehr unveränderlich Sammlungen im Rahmen zu haben, mit :)

All dies trägt dazu bei, die auto-props Seite, natürlich zu starten. Ich muss zugeben, ich habe vor kurzem eine bestimmte Menge Betrug, Fälschung Unveränderlichkeit privaten Setter mit:

public string Name { get; private set; } 

Es macht mich aber schmutzig fühlen, nicht so dass es wirklich unveränderlich, wenn das meine eigentliche Absicht ist.

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

Sie können die videos from NDC 2010 interessant finden - es gibt eine große Podiumsdiskussion mit Eric Lippert, Mads Torgersen, Neal Gafter (und mir), und meine Vorschläge für C# 5 sind in einem anderen Video.

+0

Es wäre sicherlich schön, wenn die Unveränderlichkeit erleichtert würde. Um die vollständige Unveränderlichkeit zu gewährleisten, müssen Sie alle Klassen, die Sie enthalten, vollständig unter Kontrolle haben. Zum Beispiel haben Sie gesagt, dass anonyme Typen unveränderlich sind, aber ich fügte ein Array und eine veränderbare Liste hinzu und konnte beide modifizieren. Wenn Sie ein öffentlich zugängliches Mitglied haben, das heute unveränderlich ist, kann es morgen geändert werden, und Ihre Unveränderlichkeit wird dadurch gebrochen. –

+0

Thx, ich schaue mir diese Videos an. Nach dem Lesen von etwas mehr scheint F # mit diesen Dingen auf eine schönere Art und Weise zu tun, Objekte standardmäßig zu sperren und Mutabilität zu erlauben, wenn die Notwendigkeit da ist. Ich denke, Vermächtnis stoppt das C# Team, das in diese Richtung geht. Was denkst du über F # vs C# Jon? – terjetyl

+0

@TT: Ich hatte nicht so viel Erfahrung, wie ich in F # möchte, aber ich mag verschiedene Dinge, die F #, sicherlich. Viele der Vorschläge, die ich zu C# 5 gemacht habe, basierten auf F #. –

0

Ich finde Konstrukteuren sehr sind in der Regel in C# Codebeispiele zu wenig genutzt und ich denke, Auto-Eigenschaften und Objektinitialisierer sind ein großer Teil dieser

Wenn Ihr Objekt eine Menge von Eigenschaften hat, man deutlich don Ich möchte sie 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 Objektinitialisierer sehr praktisch sind, solange die Eigenschaften nicht schreibgeschützt (aber wie Jon darauf hingewiesen, optionale Parameter in C# 4 sind eine gute Alternative)

warum funktioniert die C# Team Push-Funktionen wie diese und nicht konzentriert sich mehr auf Features liefern best Practices mehr

schieben denke ich Objektinitialisierer eingeführt wurden, weil sie für Linq notwendig waren: Sie konnten nicht anonyme 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.

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. Zum ersten Mal habe ich mich angemeldet. Und jetzt muss ich eine weitere Eigenschaft hinzufügen. Das ist verrückt!

Um die Verwendung von Objektinitialisern zu beschränken, löschte ich parameterlosen Konstruktor.

Verwandte Themen