Variablen -> Guter Programmierstil
-
Konrad Rudolph schrieb:
Simon2 schrieb:
Langer Rede kurzer Sinn:
O.o Ich glaube, das ist gerade das erste Mal, dass ich diesen Ausdruck korrekt geschrieben in einem Forum gesehen habe.
OT: Ohne da wirklich Ahnung von zu haben, so lieferte mit der erste Google-Treffer
eine Diskussion über Schiller, die folgendes feststellt:'Als falsch kann keine der beiden Formen bezeichnet werden, da "Lange Rede, kurzer Sinn" eine durch ein Komma segmentierte Aufzählung darstellt, die inhaltlich mit "langer Rede kurzer Sinn" übereinstimmt.'.
Sehe da auch keinen Unterschied.
Jockel
-
Konrad Rudolph schrieb:
Natürlich, ne Property wäre das Optimum. Aber das löst das Problem nicht, man hätte immer noch den Namenskonflikt.
das problem mit "nur um namenskonflikte aufzulösen" ist, dass man dabei inkonsistent wird.
ein public member: hat der nun eine kennzeichnung oder nicht? eigentlich nicht, weils ja hässlich ist - aber im prinzip müsste er eine haben. diese trennung public/private interface führt zu vielen solcher situationen.
vec.m_x - ist einfach nur bullshit. sowas kann man keinem programmierer antun, m_x muss deshalb x im public interface heissen.
das problem warum es überhaupt zu konflikten kommt, ist in der STL namenskonvention begründet. jede andere konvention hat diese probleme nicht.
in Java habe ich
public int getLength() { return length; }in C# habe ich
public int Length { get { return length; } }etc.
manchmal macht man sich probleme selber

-
Shade Of Mine schrieb:
das problem warum es überhaupt zu konflikten kommt, ist in der STL namenskonvention begründet. jede andere konvention hat diese probleme nicht.
in C# habe ich
public int Length { get { return length; } }Das ist ebenfalls inakzeptabel. Die Verwechslungsgefahr aufgrund kleiner/großer Buchstaben ist viel zu hoch und stellt eine subtile, schwer findbare Fehlerquelle dar (wenn in der Property z.B. noch Konsistenzprüfungen vorgenommen werden). Daher gilt für mich persönlich und auf Arbeit auch die eiserne Regel, dass Bezeichner im selben Scope nie allein durch die Groß/Kleinschreibung unterschieden werden dürfen.
-
Konrad Rudolph schrieb:
Das ist ebenfalls inakzeptabel.
und dennoch ist es industrie standard.
Die Verwechslungsgefahr aufgrund kleiner/großer Buchstaben ist viel zu hoch und stellt eine subtile, schwer findbare Fehlerquelle dar (wenn in der Property z.B. noch Konsistenzprüfungen vorgenommen werden).
nein. es liefert dir einen compiler fehler, mehr nicht.
Daher gilt für mich persönlich und auf Arbeit auch die eiserne Regel, dass Bezeichner im selben Scope nie allein durch die Groß/Kleinschreibung unterschieden werden dürfen.
schön für dich. aber man sollte immer alle facetten bedenken. zum beispiel hast du eine inkonsistente namensgebung. sei es nun m_x oder x_. m_x hat eine menge eigener probleme deshalb gehe ich mal von x_ aus. hier hat man wieder nur 1 zeichen unterschied zwischen size() und size_. Ist das viel besser als size und Size?.
-
Shade Of Mine schrieb:
Die Verwechslungsgefahr aufgrund kleiner/großer Buchstaben ist viel zu hoch und stellt eine subtile, schwer findbare Fehlerquelle dar (wenn in der Property z.B. noch Konsistenzprüfungen vorgenommen werden).
nein. es liefert dir einen compiler fehler, mehr nicht.
Soweit ich weiss liefert dich z.B.
public int Length { get { return Length; } }keinen compiler Fehler, sondern eine endlos Rekursion.
Was allerdings nicht heissen soll, dass ich diese Konvention in C# ablehne.Jockel
-
Shade Of Mine schrieb:
Konrad Rudolph schrieb:
Das ist ebenfalls inakzeptabel.
und dennoch ist es industrie standard.
Ach Quatsch. Wo ist es Industriestandard? In „der Industrie“ gibt es endlos viele Standards. Microsoft selbst verwendet intern mehrere verschiedene Konventionen (darunter den führenden Unterstrich sowie das Präfix 'm_', letzteres ziemlich durchgängig in der aktuellen Implementierung des .NET-Frameworks).
Die Verwechslungsgefahr aufgrund kleiner/großer Buchstaben ist viel zu hoch und stellt eine subtile, schwer findbare Fehlerquelle dar (wenn in der Property z.B. noch Konsistenzprüfungen vorgenommen werden).
nein. es liefert dir einen compiler fehler, mehr nicht.
Eben nicht. Es wird *gar kein* Fehler geliefert, siehe folgenden Code:
class Withdrawal { private readonly int accountBalance; private int amount; private int AccountBalance { get { return accountBalance; } } public int Amount { get { return amount; } set { if (value > accountBalance) throw new OverflowException("Es kann nur soviel Geld abgehoben werden, wie sich auf dem Konto befindet."); amount = value; } } public Withdrawal(int accountBalance) { this.accountBalance = accountBalance; } public void Perform(int amount) { this.amount = amount; // Ups, falsches Member! // Transaktion durchführen. } }; // Und jetzt folgender Aufruf: int meinKontoStand = 1000; Withdrawal ichWillMehr = new Withdrawal(meinKontoStand); ichWillMehr.Perform(2000); // Jetzt wird die Bank um 1000 EUR betrogen.Solch ein Fehler ist übrigens *nicht* rein akademisch sondern ein reell auftretendes Problem.
Daher gilt für mich persönlich und auf Arbeit auch die eiserne Regel, dass Bezeichner im selben Scope nie allein durch die Groß/Kleinschreibung unterschieden werden dürfen.
schön für dich. aber man sollte immer alle facetten bedenken. zum beispiel hast du eine inkonsistente namensgebung.
Nein, meine Namensgebung ist konsistent. Ich sehe zumindest keine Inkonsistenz. Fürs Protokoll: Ich verwende momentan durchgängig 'm_' als Präfix, auf Arbeit ist Präfix-'_' Konvention.
-
Da verstehe ich das Problem nicht. Dem Member wird einfach ein Wert zugewiesen,
ohne vorher eine Prüfung vorzunehmen. Das kann dir mit jeder anderen Konvention
doch auch passieren. Wenn man die Konvention gewohnt ist, sieht man sofort,
dass da halt nicht der Setter genommen wird, sondern direkt das Member.
-
Jockelx schrieb:
Wenn man die Konvention gewohnt ist, sieht man sofort,
dass da halt nicht der Setter genommen wird, sondern direkt das Member.Hm. Ich halte diese Unterscheidung für quasi-nichtexistend. Es gab dazu irgendwo mal nen netten Blog-Artikel: Da wir Menschen gewohnt sind, dass sich die Bedeutung eines Wortes generell nicht sehr verändert, wenn wir die Groß-/Kleinschreibung verändern, überlesen wir solche Änderungen sehr häufig. Ich halte diese Argumentation für plausibel und kann ihr aus eigener Erfahrung auch zustimmen. Außerdem vergisst man schnell mal, ne Shift-Taste zu drücken. Aber aus Versehen 'm_' zu tippen, das passiert glaube ich niemandem.
– Ich sehe hier definitiv ein großes Gefahrenpotential. Aber selbst wenn andere das für nicht so groß halten: Es lässt sich so *einfach* eliminieren.
-
Gut, mag sein. Ich nutze C# nur privat und in kleinen, übersichtlichen Projekten.
Deshalb kann ich vielleicht nicht so super mitreden. Aber zumindest da hatte
ich nie Probleme die Getter/Setter von den Membern mit dieser Konvention zu unterscheiden.Jockel
-
Konrad Rudolph schrieb:
Hm. Ich halte diese Unterscheidung für quasi-nichtexistend. Es gab dazu irgendwo mal nen netten Blog-Artikel: Da wir Menschen gewohnt sind, dass sich die Bedeutung eines Wortes generell nicht sehr verändert, wenn wir die Groß-/Kleinschreibung verändern, überlesen wir solche Änderungen sehr häufig.
und
this.accountBalance = accountBalance_;schreit nach einem fehler?
– Ich sehe hier definitiv ein großes Gefahrenpotential. Aber selbst wenn andere das für nicht so groß halten: Es lässt sich so *einfach* eliminieren.
ich sehe zwischen a und a_ nicht viel unterschied. das problem ist: will ich hier setter verwenden oder nicht? ich will eigentlich fast nie intern die checks eines set-properties haben. maximal in einem ctor. aber um ehrlich zu sein, ich weiss nicht wann ich das letzte mal einen setter hatte der mehr gemacht hat als dumme zuweisung.
und erklär mir nochmal den großen vorteil von
this.a = a_;
gegenüber
this.a = a;
ich habs nicht ganz verstanden.
-
Shade Of Mine schrieb:
und erklär mir nochmal den großen vorteil von
this.a = a_;
gegenüber
this.a = a;
ich habs nicht ganz verstanden.Musst Du auch nicht, ich finde den Unterschied auch nicht deutlich genug. Daher verwende ich auch 'm_' als Präfix. Dort ist der Unterschied allemal deutlich.
-
Konrad Rudolph schrieb:
Musst Du auch nicht, ich finde den Unterschied auch nicht deutlich genug. Daher verwende ich auch 'm_' als Präfix. Dort ist der Unterschied allemal deutlich.
das bringt aber ein enormes intellisense problem mit sich: intellisense fast nutzlos. das schränkt die produktivitaet ein.
weiters gibt das selbe argument wie bei groß/kleinschreibung:
der mensch erkennt ein wort anhand der ersten paar buchstaben. bzw, die ersten paar buchstaben sind signifikant.das ist zB ein grund warum gross/kleinschreibung wieder halbwegs funktioniert, weil der 1. buchstabe das ist was du als erstes erkennst

-
Shade Of Mine schrieb:
Konrad Rudolph schrieb:
Musst Du auch nicht, ich finde den Unterschied auch nicht deutlich genug. Daher verwende ich auch 'm_' als Präfix. Dort ist der Unterschied allemal deutlich.
das bringt aber ein enormes intellisense problem mit sich: intellisense fast nutzlos. das schränkt die produktivitaet ein.
Inwiefern? Kann ich nicht nachvollziehen. (Ich greife ja nur aus der Property selbst auf das Feld zu).
der mensch erkennt ein wort anhand der ersten paar buchstaben. bzw, die ersten paar buchstaben sind signifikant.
das ist zB ein grund warum gross/kleinschreibung wieder halbwegs funktioniert, weil der 1. buchstabe das ist was du als erstes erkennst

Aha … das erzählst Du mir in einem C++-Form … alles klar.

– Du hast ja recht. Aber ein durch '_' getrenntes Präfix kann man für sowas ziemlich gut „ausblenden“.
Siehe auch: http://dotnet.mvps.org/dotnet/articles/camelcase/
Der Artikel bringt das ziemlich gut auf den Punkt und ist m.E. der beste zu diesem Thema.
-
Konrad Rudolph schrieb:
Inwiefern? Kann ich nicht nachvollziehen. (Ich greife ja nur aus der Property selbst auf das Feld zu).
du hast für jede variable ein property??
Aha … das erzählst Du mir in einem C++-Form … alles klar.

– Du hast ja recht. Aber ein durch '_' getrenntes Präfix kann man für sowas ziemlich gut „ausblenden“.
genauso leicht wie man einen gross/klein buchstaben als signifikant ansehen kann

Siehe auch: http://dotnet.mvps.org/dotnet/articles/camelcase/
Der Artikel bringt das ziemlich gut auf den Punkt und ist m.E. der beste zu diesem Thema.
es gibt einen unterschied zwischen "das beste wo gibt" und "genauso fehlerbehaftet wie X"

ich habe nie gesagt dass ein Stil der beste ist. ich habe lediglich mehrere alternativen zu deinem stil gezeigt wie man gewisse probleme die du hast umgehen kann.
-
Shade Of Mine schrieb:
Konrad Rudolph schrieb:
Inwiefern? Kann ich nicht nachvollziehen. (Ich greife ja nur aus der Property selbst auf das Feld zu).
du hast für jede variable ein property??
Kommt drauf an. Wenn ich in VB oder C# programmiere schon, denn da erstellt mir die IDE die ja quasi automatisch (und der Compiler kann sie eh schön wegoptimieren). In C++ erstelle ich, mangels schöner Syntax, fast nie Getter/Setter, es sei denn, ich brauche sie (eben wegen einer Bereichsüberprüfung oder was-weiß-ich). Java programmiere ich nicht, aber wenn ich es tue, dann halte ich mich hier an die Richtlinien und erstelle auch für alles Getter und Setter und komme mir extrem affig vor.
ich habe nie gesagt dass ein Stil der beste ist. ich habe lediglich mehrere alternativen zu deinem stil gezeigt wie man gewisse probleme die du hast umgehen kann.
Jap, ist auch so angekommen. Das ist doch der Sinn einer Diskussion. Wenn alles ganz klar und einfach wäre, bräuchten wir das Forum nicht.

-
Also ich benutz eigentlich auch für alles properties, da die dann in der IDE diese bilder(eine list mit einer hand drauf) haben, dass lässt dann diese dinger im intelliSense wirklich hervorstechen. Somit kann ich die öffentlichen interfaces(oder anderer terminus gefällig?) sehr leicht identifizieren ohne, dass ich groß auf den namen achten muss.
-
Also ich habe quasi nie Properties - egal welche Sprache. Property ist für mich ein Accessor und den brauche ich nur, wenn er zum Public Interface gehoert...
wenn ich mir selbst mit den richtigen werten nicht vertraue, dann baue ich wohl lieber invarianten ein :p