gibt es in C# optionale Parameter?
Was möchte ich?
Einmal aufrufen so:
Report(Print,"Drucke");
Einmal aufrufen so:
Report(Print,"Drucke2", 47,3);
Grüße Sandra
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public Report(ReportType Type, string Message, int Count, int
CountActual)
{
this.m_Type = Type;
this.m_Message = Message;
this.Count = Count;
this.CountActual = CountActual;
}
"Sandra Müller" <so...@arcor.de> schrieb:
>gibt es in C# optionale Parameter?
Leider nicht.
>Was möchte ich?
>
>Einmal aufrufen so:
> Report(Print,"Drucke");
>
>Einmal aufrufen so:
> Report(Print,"Drucke2", 47,3);
Erstelle zwei Methoden gleichen Namens, die sich in ihrer Argumentliste
unterscheiden:
\\\
private void Report(string x, string y, double z)
{
...
}
private void Report(string x, string y)
{
Report(x, y, 50.0);
}
///
--
M S Herfried K. Wagner
M V P <URL:http://dotnet.mvps.org/>
V B <URL:http://classicvb.org/petition/>
> gibt es in C# optionale Parameter?
nein, weil
http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
üblich ist: Methoden-Überladung.
ggf verwandtes Thema:
http://msdn.microsoft.com/library/DEU/csref/html/vclrfParams.asp
--
Thomas Scheidegger - MVP .NET - 'NETMaster'
http://www.cetus-links.org/oo_dotnet.html - http://dnetmaster.net/
> gibt es in C# optionale Parameter?
quasi ~ja, durch die "params"-Parameter Möglichkeit.
Kommt aber darauf an, wie man das definiert.
[params (C#-Referenz)]
http://msdn2.microsoft.com/de-de/library/w5zay9db.aspx
>Was möchte ich?
> Report(Print,"Drucke");
> Report(Print,"Drucke2", 47,3);
Zum Beispiel:
public enum ReportType{Print, Draw}
private void Form1_Load(object sender, System.EventArgs e)
{ new Report(ReportType.Print,"Drucke");
new Report(ReportType.Print,"Drucke2", 47,3);
}
class Report
{ public Report(ReportType type, string message, int count, int countActual)
{ this.RepType = type;
this.Message = message;
}
public Report(ReportType type, string message) : this(type, message, 0,0){}
public ReportType RepType;
public string Message;
}
ciao Frank
--
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET
> gibt es in C# optionale Parameter?
im Prinzip ja: schau Dir
http://msdn2.microsoft.com/de-de/library/w5zay9db.aspx
an
Grüße
Holger
leider.
Wobei die im link angegebenen Argumente IMHO nicht stichhaltig sind.
1. Verständlichkeit
Wenn ich etwas wie
File.Open(string fn, FileMode, FileAccess fa = FileAccess.ReadWrite);
sehe, weiß ich a.) dass der Aufruf eine FileAccess-Spec haben kann und
b.) dass diese normalerweise auf ReadWrite steht.
Wenn ich - wie in C# - etwas wie
File.Open(string fn, FileMode fm ) { ... }
sehe, weiß ich das zunächst mal nicht. Ich muss im Code wesentlich
weiter lesen, nämlich bis ich zu der Stelle
File.Open(string fn, FileMode fm, FileAccess fa ) { ... }
komme. Dann erkenne ich, dass die Funktion überladen ist. Jetzt blättere
ich zurück und vergleiche beide Funktionen miteinenader. Wo ist der
Unterschied? Gibt es - wie hier - nur einen zusätzlichen Parameter, oder
sind die Parameterlisten ganz anders?
Als nächster Schritt muss ich nun noch weiter nach unten schauen -
vielleicht gibt es ja einen weiteren overload? Vielleicht noch weitere
optionale Parameter?
Ich sage dir - nach 10 Stunden Programmieren möchte man sich diesen
geistigen Aufwand gerne ersparen! UND - wir wissen immer noch nicht, wie
der default-Wert für FileAccess im Falle
File.Open(string fn, FileMode fm ) { ... }
ist. Dazu müssen wir nämlich den Quellcode der Implementierung der
Funktion untersuchen. Schauder!
Ich würde gerne einem Funktionskopf ansehen, ob eine Funktion das tut,
was ich will, oder nicht. Dazu möchte ich nicht durch die
IMplementierung gehen müssen.
2. Restliche Argumente aus dem Beitrag genau so, hier nicht weiter
ausgeführt.
Grüße - Paule
"Paul Werkowitz" <newsg...@primaprogramm.de> schrieb:
>> > gibt es in C# optionale Parameter?
>>
>> nein, weil
>> http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
>
> leider.
>
> Wobei die im link angegebenen Argumente IMHO nicht stichhaltig sind.
Das sehe ich auch so (Argumente weiter unten).
> 1. Verständlichkeit
>
> Wenn ich etwas wie
>
> File.Open(string fn, FileMode, FileAccess fa = FileAccess.ReadWrite);
>
> sehe, weiß ich a.) dass der Aufruf eine FileAccess-Spec haben kann und b.)
> dass diese normalerweise auf ReadWrite steht.
>
> Wenn ich - wie in C# - etwas wie
>
> File.Open(string fn, FileMode fm ) { ... }
>
> sehe, weiß ich das zunächst mal nicht. Ich muss im Code wesentlich weiter
> lesen, nämlich bis ich zu der Stelle
>
> File.Open(string fn, FileMode fm, FileAccess fa ) { ... }
>
> komme. Dann erkenne ich, dass die Funktion überladen ist. Jetzt blättere
> ich zurück und vergleiche beide Funktionen miteinenader. Wo ist der
> Unterschied? Gibt es - wie hier - nur einen zusätzlichen Parameter, oder
> sind die Parameterlisten ganz anders?
>
> Als nächster Schritt muss ich nun noch weiter nach unten schauen -
> vielleicht gibt es ja einen weiteren overload? Vielleicht noch weitere
> optionale Parameter?
>
> Ich sage dir - nach 10 Stunden Programmieren möchte man sich diesen
> geistigen Aufwand gerne ersparen! UND - wir wissen immer noch nicht, wie
> der default-Wert für FileAccess im Falle
>
> File.Open(string fn, FileMode fm ) { ... }
>
> ist. Dazu müssen wir nämlich den Quellcode der Implementierung der
> Funktion untersuchen. Schauder!
... oder in der Dokumentation nachlesen. Das ist aber auch unnötig
aufwendig, da die Entwicklungsumgebung verlassen bzw. das Fenster gewechselt
werden muss. Zudem ist nicht sichergestellt, dass dort auch auf den
übergebenen Parameterwert eingegangen wird.
Meine Sicht der Dinge zu den "Argumenten" im Artikel von Eric Gunnerson:
| In other words, the compiler takes the default value that is specified
| in the method prototype and puts it into the method call - it's just as if
| the user wrote 'false' as the second parameter. There's no way to change
| that default value without forcing the user of the class to recompile,
which
| is unfortunate.
Ich halte es nicht für unglücklich, dass der Wert des optionalen Parameters
nicht geändert werden darf, ohne dass abhängige Bibliotheken neu kompiliert
werden müssen.
Ein optionaler Parameter mit seinem Standardwert ist schlichtweg ein
Vertrag, den der Hersteller der Komponente, welche die Methode mit dem
optionalen Parameter enthält, nicht einfach so aus Lust und Laune heraus
brechen darf. So würde auch das Hinzufügen eines zusätzlichen Parameters zu
einer Methode oder das Ändern eines Parametertyps dazu führen, dass neu
kompiliert werden müsste. Das von Eric Gunnerson genannte Szenario ist also
in einem professionellen Umfeld rein theoretischer Natur.
| The overloading model works better in this respect. The framework
| author just defines two separate methods, and the single-parameter
| one calls the two-parameter method. This keeps the default value in
| the framework, where it can be modified if necessary.
Der Witz an der Sache ist ja, dass eben der Standardwert nicht einfach so
geändert werden darf, da er in den meisten Fällen kein für den Benutzer der
Methode transparentes Implementierungsdetail darstellt. Vielmehr ist die
Kenntnis des Standardwertes oft von grosser Bedeutung, weshalb ein Ändern
des Standardwertes in der Praxis ohnehin nicht vorkommen wird.
| The first one is that the correlation between the code that the
| user writes and the code the compiler generates is less obvious.
| We generally try to limit magic when possible, as it makes it harder
| for programmers.
Ich halte es für magischer, wenn Standardwerte benutzt werden, die unbekannt
sind, als wenn diese direkt sichtbar sind. Ein weiteres unschönes Problem
ist, dass man oft mit Überladungen überhäuft wird, die wesentlich schlechter
handhabbar sind, als eine entsprechende Lösung mit optionalen Parametern
(vgl. 21 (!) Überladungen bei 'MessageBox.Show' in .NET 2.0 vs. 'MsgBox' in
VB.NET).
| The second issue has to do with things like XML doc comments and
| intellisense. The compiler would have to have special rules for how it
| generates doc comments for the overloaded methods, and intellisense
| would need to have smarts to collapse the overloaded methods into a
| single method.
Das ist doch hoffentlich nicht ernst gemeint. Für einen professionellen
Compilerentwickler sollte die Unterstützung für optionale Parameter wirklich
keine unüberwindbare Hürde darstellen.
Du sprichts mir aus der Seele. Ich möchte das nicht weiter aufrollen, da
wir hier einer Meinung sind. Ich hatte meine Argumentation nicht weiter
fortgeführt, da mein Posting eh schon lang genug war.
Einige Anmerkungen:
>> ist. Dazu müssen wir nämlich den Quellcode der Implementierung der
>> Funktion untersuchen. Schauder!
>
> ... oder in der Dokumentation nachlesen. Das ist aber auch unnötig
> aufwendig, da die Entwicklungsumgebung verlassen bzw. das Fenster
> gewechselt werden muss. Zudem ist nicht sichergestellt, dass dort auch
> auf den übergebenen Parameterwert eingegangen wird.
>
Hinzu kommt erschwerend, dass Dokumentation dazu tendiert, sich von der
Wahrheit zu entfernen. In unserem Projekt drehen wir alles ständig durch
den Wolf (sehr agiler Ansatz), und keiner will wirklich alle Dokus auf
dem korrekten Stand halten. Nein! - der Code muss die Doku sein, so weit
es geht. Dazu müssen wir Anforderungen an die Lesbarkeit des Codes
stellen, nicht Doku schreiben.
> Meine Sicht der Dinge zu den "Argumenten" im Artikel von Eric Gunnerson:
>
full ack.
OTOH: was könnte es sein, dass in C# auf das Feature verzichtet wurde?
In VB.NET haben wir OPTIONAL, in C++/CLI weiterhin die Vorgabeparameter.
Paul
ganz klar:
C# = sharp, lean and clean...
Praktisch alle anderen 'Programmiersprachen' sind heute dagegen 'zugemüllt'
mit Unsinn und Altlasten....
"Thomas Scheidegger [MVP]" <spam.ne...@swissonline.ch> schrieb:
>> was könnte es sein, dass in C# auf das Feature verzichtet wurde?
>
> ganz klar:
>
> C# = sharp, lean and clean...
>
> Praktisch alle anderen 'Programmiersprachen' sind heute dagegen
> 'zugemüllt'
> mit Unsinn und Altlasten....
Könntest du Argumente bringen, die deine Aussagen unterstützen?
Erkläre doch bitte, wo du den Vorteil zahlreicher Überladungen gegenüber
einer Methode mit optionalen Parametern siehst. Du willst doch nicht
ernsthaft behaupten, 'MessageBox.Show' mit seinen 21 Überladungen sei
einfacher zu benutzen als 'MsgBox'. Oder anders: Änderst du beliebig
Schnittstellen, gegen die andere Entwickler Code geschrieben haben?
Optionale Parameter werden von IL/CLR und einigen anderen
.NET-Programmiersprachen unterstützt (und zwar so, wie sie eben unterstützt
werden, dass auf Aufruferseite der Standardwert in der IL vom Compiler
hinterlegt wird). Daher ist es völlig unverständlich, warum mit weichen,
praxisfernen Argumenten versucht wird, deren Integration in C# zu
unterbinden.
ganz einfach, Kontrolle und nur explizite Angaben:
ich will Parameter nur entweder
- bei mir im SourceCode stehen haben,
- oder in der Library/Framework (bzw dessen Doku).
Der Compiler soll nicht _auch_ noch _heimlich_ sein Zeugs reinkleben...
Im Sinne eben von
http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
"...that the correlation between the code that the user writes
and the code the compiler generates is less obvious"
C# Source ist daher immer glasklar
(+ der daraus enstehende MSILcode ist sehr gut abschätzbar)
Reine Konzepte sind die wahre Kunst, überfrachtete Sprachen kann jeder basteln.
sag mal, hast du eigentlich mein Posting von 13:00 Uhr nicht gelesen?
Kommst du wieder mit den gleichen Argumenten, die längst widerlegt sind?
>
> C# Source ist daher immer glasklar
> (+ der daraus enstehende MSILcode ist sehr gut abschätzbar)
> Reine Konzepte sind die wahre Kunst, überfrachtete Sprachen kann jeder basteln.
>
Glasklar? Dann sage mir doch mal bitte nach dem Lesen folgender Deklaration
File.Open(string fn, FileMode fm ) { .... }
wieviele optionale Parameter du noch angeben kannst, und welche
Default-Werte diese haben. Diese Information würde ich gerne haben, um
File.Open korrekt benutzen zu können.
Um sie zu gewinnen, muss ich in C# allerdings Unmengen Sourcecode
durchblättern, da es ja noch irgendwo eine überladene Funktion mit
zusätzlichn Params geben kann.
Habe ich dann vielleicht irgendwann etwas wie
File.Open(string fn, FileMode fm, FileAccess fa ) { ... }
gefunden, weiß ich zumindest, dass es einen zusätzlichen
FileAccess-Parameter geben kann. Welcher Default-Wert in 99% aller Fälle
der Richtige ist, weiß ich allerdings immer noch nicht. Dazu muss ich
nämlich den Code von
File.Open(string fn, FileMode fm ) { .... }
untersuchen, denn dort steht er ja wahrscheinlich hardcodiert (!) drin.
Das nur zum Thema *glasklar*
Für *mich* wäre da eher etwas wie
File.Open(string fn, FileMode, FileAccess fa = FileAccess.ReadWrite)
{ ... }
am aller glas-klarsten.
Aber vielleicht kannst du deine Gedanken etwas ausbreiten? Aus Sätzen wie
>ich will Parameter nur entweder
> - bei mir im SourceCode stehen haben,
> - oder in der Library/Framework (bzw dessen Doku).
wird nicht klar, warum dies *allgemein* wünschenswert wäre (d.h. über
deine persönliche Präferenz hinaus).
Grüße - Paule
Der Compiler klebt bei jedem Methodenaufruf heimlich den Methodenaufruf
hinein. Unverschämt!
> Im Sinne eben von
> http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
> "...that the correlation between the code that the user writes
> and the code the compiler generates is less obvious"
Diese Korrelation ist /immer/ offensichtlich. Wenn hier ein 'Optional' steht
(im Code, in der Methodensignatur, in IntelliSense beim Schreiben des
Aufrufs und in der Dokumentation), dann ist es vollkommen offensichtlich,
dass hier ein bestimmter, dokumentierter Wert übergeben wird.
Offensichtlicher geht es wohl kaum, ausser, du übergibst den Standardwert
explizit oder nützt immer die Überladung, welche die meisten Parameter
besitzt, sofern es sich bei allen weiteren Überladungen nur um Aufrufe der
meistparametrigen unter Übergabe von Standardwerten handelt.
> C# Source ist daher immer glasklar
Gerade das ist, wie von Paul gezeigt wurde, nicht der Fall, da bei
Verwendung von Überladungen an Stellen, an denen die Kenntnis des
übergebenen Standardwertes von Bedeutung ist, dieser nicht ersichtlich ist.
> (+ der daraus enstehende MSILcode ist sehr gut abschätzbar)
Das ist er auch bei 'Optional' bzw. beim Konsumieren einer Methode mit
optionalen Parametern. Zudem ist es doch eher unwichtig (Stichwörter:
Hochsprache, Abstraktion, Transparenz, Information Hiding), dass man genau
nachvollziehen kann, welche IL vom Compiler emittiert wird.
> Reine Konzepte sind die wahre Kunst, überfrachtete Sprachen kann jeder
> basteln.
Du willst es nicht verstehen.
solches gehört etwa in IntelliSense o.ä.,
aber nicht heimlich in den Compiler/IL-Code fest verdrahtet wie eben bei opt.params.
> >ich will Parameter nur entweder
> > - bei mir im SourceCode stehen haben,
> > - oder in der Library/Framework (bzw dessen Doku).
> wird nicht klar, warum dies *allgemein* wünschenswert wäre (d.h. über
> deine persönliche Präferenz hinaus).
wenn man eine breite 'Volksbefragung' zu neuen Features/Programmiersprachen macht,
kommen sofort tausende Wünsche und kuriose Begehren ...
In der Vergangenheit hat dies _stets_ zu überladenen Chaoten-Sprachen geführt.
Meine 'Präferenz' (und AFAIK offenbar eher auch Microsofts C# Team/Hejlsberg/Gunnerson)
ist eben lieber: lean & clean, nicht 'Bequemlichkeit' um jeden Preis...
Man hat da eben auch aus den Fehlern von anderen/älteren Sprachen dazugelernt....
klar, mit deiner VB-Denkweise kannst du C# niemals begreifen.
Deine Beiträge strotzen heute wieder nur so vor Argumenten...
meine und Microsofts Argumente
http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
sind relevant und absolut überzeugend, nicht was gelegentlich ein VB-Hirn erspinnt....
Nochmals, in C# gibt es eben einen übergeordneten lean & clean Grundsatz,
wem das nicht passt oder nicht begreift dann ist das sein Problem...
C# ist so oder so die erfolgreichste Sprache dieses Jahrtausends.
OK; hier haben wir es wieder, das Killerargument. "Intellisennse".
Varianten dieser Argumentation (bei den Java-Jüngern sehr beliebt):
"dafür gibts (formale) Dokumentation", etc.
Sorry! Falsch! Wir wollen eine Sprache, in der man Konzepte durch
Sprachmittel ausdrücken kann. Fehlende Sprachmittel können niemals durch
externe Werkzeuge wie "intelligente" Editoren oder "intelligente"
Dokugeneratoren ersetzt werden.
Oder anders herum: Wenn ich Intellisense *brauche*, um vernünftig
programmieren zu können, dann ist was falsch.
Ich habe dir in meinem geschilderten Szenario eine Situation aufgezeigt,
in der Default-Argumente nützlich sind. Darüber hinaus habe ich auch
gezeigt, dass Default-Argumente dem Überladen überlegen sind, und ich
habe Argumente dafür gegeben.
Vielleicht kannst du deine Position ebenfalls begründen?
> > >ich will Parameter nur entweder
> > > - bei mir im SourceCode stehen haben,
> > > - oder in der Library/Framework (bzw dessen Doku).
> > wird nicht klar, warum dies *allgemein* wünschenswert wäre (d.h. über
> > deine persönliche Präferenz hinaus).
>
> wenn man eine breite 'Volksbefragung' zu neuen Features/Programmiersprachen macht,
> kommen sofort tausende Wünsche und kuriose Begehren ...
> In der Vergangenheit hat dies _stets_ zu überladenen Chaoten-Sprachen geführt.
korrekt. Deswegen macht das auch keiner. Bzw. (um den Seitenhieb auf C++
zu kommentieren): dort gibt es ein Komitee, das gewünschte
Spracherweiterungen diskutiert - und 99% davon ablehnt....
Trotzdem: es ist keine Antwort auf meine Frage: es wird nicht klar,
warum der Verzicht auf Default-Argumente *allgemein* wünschenswert wäre.
>
> Meine 'Präferenz' (und AFAIK offenbar eher auch Microsofts C# Team/Hejlsberg/Gunnerson)
> ist eben lieber: lean & clean, nicht 'Bequemlichkeit' um jeden Preis...
> Man hat da eben auch aus den Fehlern von anderen/älteren Sprachen dazugelernt....
>
Wie gesagt, ich warte immer noch darauf, dass du mal sagst, warum
Default-Argumente schlecht sind. Und, bitte, die Argumentation von
Gunnerson ist nicht stichhaltig, wie bereits andere hier festgestellt
haben.
Und, BTW, V1 der Sprache hatte keine Generics, keine partiellen Klassen
etc. Wenn man nur nach "lean & clean" geht, wären z.B. Generics heute
noch nicht drin. Schau dir mal das V2-Dokument an! Da ist die
Beschreibung der Generics so lang wie der gesamte Rest zusammen! Also:
lean&clean alleine kann's nicht sein, was eine gute Sprache ausmacht.
Wenn du deiner Meinung wirklich treu bist, lehnst du Generics sicher
auch ab, wie die Java-Leute das jahrelang gemacht haben (C++ hat
Templates. C++ ist böse, böse, böse.... => Generics brauchen wir nicht
... ).
Paule.
Im Übrigen gibt Gunnerson ja selber Argumente an, warum er keine
Default-Argumente haben wollte. lean&clean gehört aber nicht dazu. Er
schreibt:
>Writing overloads yourself is a bit less convenient...
than having default arguments, muss man hier ergänzen.
Meinungen ändern sich, neue Erkenntnisse kommen dazu. Bei der Definition
von C# hat man sich bewußt gegen Generics entschieden. Irgendwann haben
die Gurus ihre Meinung geändert - jetzt haben wir sie. Die Sprache wäre
ohne sie leaner and cleaner - trotzem sind sie nun dabei. lean&clean
kann also nicht die Maßgabe für die Definition einer brauchbaren Sprache
sein.
> C# ist so oder so die erfolgreichste Sprache dieses Jahrtausends.
Bezweifle ich. Große Systeme werden nach wie vor in C++ geschrieben. Der
Vorteil von C# ist lediglich, dass es gut ins .NET Konzept passt. Als
Profi bist du mit C++/CLI besser bedient.
Paule
'lean & clean' ist der Grundsatz von C# insgesamt,
nicht nur bei Default-Params...
Aber lies auch nochmals die ähnliche Äusserung von
http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
"...correlation between the code that the user writes
and the code the compiler generates is less obvious.
We generally try to __limit__magic__ when possible, as it makes it harder for programmers"
> Meinungen ändern sich, neue Erkenntnisse kommen dazu. Bei der Definition
> von C# hat man sich bewußt gegen Generics entschieden.
meinen Informationen zufolge, etwa Microsoft-Research (u.a. May 2001, .NET 1.0 war erst in Beta!)
http://research.microsoft.com/projects/clrgen/
hat Microsoft Generics durchaus schon _sehr_ früh auch immer in Erwägung gezogen,
aber aus Prioritätsgründen noch nicht in der 1.x implementiert.
Denn Generics setzen umfassenden Support in der CLR-Runtime, JITer und Frameworklassen voraus.
Auf Default-Params dagegen scheint mir viel bewusster verzichtet worden....
> > C# ist so oder so die erfolgreichste Sprache dieses Jahrtausends.
> Bezweifle ich. Große Systeme werden nach wie vor in C++ geschrieben.
C/C++: 1970/1983 = letztes Jahrtausend!
> mit C++/CLI besser bedient
nein, macht nur übergangsweise bei Technologie-Mixturen Sinn.
(und C++/CLI kommt eh zu spät)
"Thomas Scheidegger [MVP]" <spam.ne...@swissonline.ch> schrieb:
> >> klar, mit deiner VB-Denkweise kannst du C# niemals begreifen.
> > Deine Beiträge strotzen heute wieder nur so vor Argumenten...
>
> meine und Microsofts Argumente
> http://blogs.msdn.com/csharpfaq/archive/2004/03/07/85556.aspx
> sind relevant und absolut überzeugend, nicht was gelegentlich ein VB-Hirn
> erspinnt....
Im Gegensatz zu deinem C#-Hirn schaffe ich es, über den Tellerrand zu
blicken und Dinge in ihrem eigenen Kontext zu analysieren. Dass VB zufällig
optionale Parameter unterstützt, ist doch vollkommen nebensächlich. Nicht
alles an VB ist nur deshalb gut, weil es in VB enthalten ist. Hier
unterscheiden sich unsere Sichtweisen. Wenn es nach dir geht, ist C# "per
Definition" perfekt.
> Der Witz an der Sache ist ja, dass eben der Standardwert nicht einfach
> so geändert werden darf, da er in den meisten Fällen kein für den
> Benutzer der Methode transparentes Implementierungsdetail darstellt.
> Vielmehr ist die Kenntnis des Standardwertes oft von grosser
> Bedeutung, weshalb ein Ändern des Standardwertes in der Praxis ohnehin
> nicht vorkommen wird.
Ansich sollte es allerdings völlig problemlos sein die Standardwerte
in Methoden zu verändern, solange kein Breaking Change dabei auftritt,
also z.B: sicherheitstechnisch etwas restriktiver wird, etc.. Es
muss halt lediglich das dokumentierte Verhalten beibehalten werden,
wie das gemacht wird ist ja letztendlich egal.
> Das ist er auch bei 'Optional' bzw. beim Konsumieren einer Methode mit
> optionalen Parametern. Zudem ist es doch eher unwichtig (Stichwörter:
> Hochsprache, Abstraktion, Transparenz, Information Hiding), dass man
> genau nachvollziehen kann, welche IL vom Compiler emittiert wird.
Wenn du schon Stichwörter wie "Information Hiding" erwähnst, frag ich
mich, woher du weißt, welche überladenen Methoden intern sozusagen
default Parameter verwenden? Zwar liest man derartige Informationen
oftmals in der Dokumentation, allerdings meine ich, dass sowas auf
"dokumentier-faule" Entwickler hinweist, denn letztendlich beschreibt
er damit wie die Methode macht, was sie eben macht, was wiederum ein
Verstoß gegen "Information Hiding" ansich ist.
> So würde auch das Hinzufügen eines zusätzlichen Parameters zu einer
> Methode oder das Ändern eines Parametertyps dazu führen, dass neu
> kompiliert werden müsste. Das von Eric Gunnerson genannte Szenario ist
> also in einem professionellen Umfeld rein theoretischer Natur.
Klar, das sind natürlich Breaking Changes, da du die öffentliche
Schnittstelle veränderst, hat aber kaum etwas mit denen zu tun,
die bei Verändern des Verhaltens einer Methode entstehen.
Das Problem für mich bei optionalen Parametern ist dieses "Replace"
des Aufrufs mit dem default Parameter, der somit in der Assembly
"hard-codiert" vorhanden ist. Sobald ich jetzt diesen default
Parameter intern veränder funktioniert es nämlich anscheinend,
wobei allerdings sämtliche ältere Assemblies, also jene, die nicht
neu kompiliert wurden, nach wie vor den alten default Parameter
verwenden. Wiederum wird also ersichtlich, dass optionale Parameter
meiner Meinung nach gegen Information Hiding verstossen.
Übrigens bin ich auch der Meinung, dass C# lean&clean bleiben soll,
wodurch ich auch eher skeptisch auf Features wie Extension Methods,
etc... reagiere.
grüße
Bernhard Huemer
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > Das ist er auch bei 'Optional' bzw. beim Konsumieren einer Methode mit
> > optionalen Parametern. Zudem ist es doch eher unwichtig (Stichwörter:
> > Hochsprache, Abstraktion, Transparenz, Information Hiding), dass man
> > genau nachvollziehen kann, welche IL vom Compiler emittiert wird.
>
> Wenn du schon Stichwörter wie "Information Hiding" erwähnst, frag ich
> mich, woher du weißt, welche überladenen Methoden intern sozusagen
> default Parameter verwenden? Zwar liest man derartige Informationen
> oftmals in der Dokumentation, allerdings meine ich, dass sowas auf
> "dokumentier-faule" Entwickler hinweist, denn letztendlich beschreibt
> er damit wie die Methode macht, was sie eben macht, was wiederum ein
> Verstoß gegen "Information Hiding" ansich ist.
An dieser Stelle kann ich nur wieder auf das von Paul vorgestellte
Dateizugriffsbeispiel verweisen. Letztlich wird die überwiegende Mehrzahl
der Überladungen eine bestimmte Methode aufrufen. Allerdings ist klar, dass
optionale Parameter nicht in allen Fällen einen probaten Ersatz für
Überladen darstellen.
> > So würde auch das Hinzufügen eines zusätzlichen Parameters zu einer
> > Methode oder das Ändern eines Parametertyps dazu führen, dass neu
> > kompiliert werden müsste. Das von Eric Gunnerson genannte Szenario ist
> > also in einem professionellen Umfeld rein theoretischer Natur.
>
> Klar, das sind natürlich Breaking Changes, da du die öffentliche
> Schnittstelle veränderst, hat aber kaum etwas mit denen zu tun,
> die bei Verändern des Verhaltens einer Methode entstehen.
Deshalb bezog ich mich ja rein auf die Schnittstelle (Methodensignaturen, in
der Dokumentation zugesichertes Verhalten). Die Schnittstelle /muss/
konstant bleiben und darf sich nicht ändern, stattdessen müssen ggf. neue
Methoden anderen Namens eingeführt werden.
> Das Problem für mich bei optionalen Parametern ist dieses "Replace"
> des Aufrufs mit dem default Parameter, der somit in der Assembly
> "hard-codiert" vorhanden ist. Sobald ich jetzt diesen default
> Parameter intern veränder funktioniert es nämlich anscheinend,
> wobei allerdings sämtliche ältere Assemblies, also jene, die nicht
> neu kompiliert wurden, nach wie vor den alten default Parameter
> verwenden. Wiederum wird also ersichtlich, dass optionale Parameter
> meiner Meinung nach gegen Information Hiding verstossen.
Hier müssten evtl. Compiler und CLR angepasst/erweitert werden, sodass sie
derartige Szenarien erkennen können (Abgleich des Standardwertes in der
Bibliothek mit jenem, der (mit einem Attribut als optionaler Parameter
markiert) übergeben wird und ggf. Werfen einer Ausnahme. Vermutlich sind
auch andere Ansätze denkbar.
> Übrigens bin ich auch der Meinung, dass C# lean&clean bleiben soll,
> wodurch ich auch eher skeptisch auf Features wie Extension Methods,
> etc... reagiere.
Auch ich stehe derartigen Erweiterungen teils kritisch gegenüber.
für technologische Fehl-Analysen bist du ja bekannt.... (siehe zB immer noch deine Sig mit VB.EX-Petition)
> ist C# "per Definition" perfekt.
nicht ganz, aber für das heutige Umfeld genug nahe dran.
Mindestens gibt es in C# zusammen mit .NET eine besondere Gradlinigkeit und Konsequenz,
womit absolut keine andere (Markt-relevante) Sprache mithalten kann.
Überfrachtete Sprachen gibts genug.
Früher oder später mag es wieder bessere 'Sprachen/Konzepte' geben,
bis dahin setze ich (und Microsoft, und sehr, sehr viele andere) auf die führende (managed-) Sprache.
> An dieser Stelle kann ich nur wieder auf das von Paul vorgestellte
> Dateizugriffsbeispiel verweisen. Letztlich wird die überwiegende
> Mehrzahl der Überladungen eine bestimmte Methode aufrufen.
Ich hingegen halte das Beispiel nicht für sehr gelungen, weil mich
persönlich Überladungen von File.Open nicht interessieren, wenn ich
doch nur eine bestimmte Version (eben File.Open(string, FileMode))
verwenden will:
> Wenn ich etwas wie
>
> File.Open(string fn, FileMode, FileAccess fa = FileAccess.ReadWrite);
>
> sehe, weiß ich a.) dass der Aufruf eine FileAccess-Spec haben kann
und > b.) dass diese normalerweise auf ReadWrite steht.
>
> Wenn ich - wie in C# - etwas wie
>
> File.Open(string fn, FileMode fm ) { ... }
>
> sehe, weiß ich das zunächst mal nicht.
> wieviele optionale Parameter du noch angeben kannst, und welche
> Default-Werte diese haben. Diese Information würde ich gerne haben, um
> File.Open korrekt benutzen zu können.
>
> Um sie zu gewinnen, muss ich in C# allerdings Unmengen Sourcecode
> durchblättern, da es ja noch irgendwo eine überladene Funktion mit
> zusätzlichn Params geben kann.
Hier fängt für mich der Irrtum an, denn was wird gemacht um die
Funktionsweise von File.Open zu erläutern: Überladungen betrachten,
bevor ich in der Dokumentation nachsehe? "Öffnet einen FileStream
für den angegebenen Pfad mit Lese- und Schreibzugriff." [1]
In der Erläuterung wirkt es ja förmlich als könnte man davon ausgehen,
dass es sich um eine Überladung handelt, die optionale Parameter
nachbilden soll, aber das /kann/ man, bzw. besser gesagt /darf/ man
eigentlich nicht wissen, nachdem es in der Dokumentation ja nicht
explizit erwähnt wurde und somit ein Implementierungsdetail ist,
dass sich ohne weiteres ändern kann.
> Deshalb bezog ich mich ja rein auf die Schnittstelle
> (Methodensignaturen, in der Dokumentation zugesichertes Verhalten).
> Die Schnittstelle /muss/ konstant bleiben und darf sich nicht ändern,
> stattdessen müssen ggf. neue Methoden anderen Namens eingeführt
> werden.
Natürlich muss die Schnittstelle konstant bleiben, aber aufgrund der
"hard-codierten" default Parameter /kann/ sie das bei Veränderungen
von optionalen Parametern nicht. Bei Überladungen ist das nicht der
Fall sofern man nicht einen, ich sag einfach mal "soft" Breaking
Change, der die Dokumentation "verletzt", einbaut.
> Hier müssten evtl. Compiler und CLR angepasst/erweitert werden, sodass
> sie derartige Szenarien erkennen können (Abgleich des Standardwertes
> in der Bibliothek mit jenem, der (mit einem Attribut als optionaler
> Parameter markiert) übergeben wird und ggf. Werfen einer Ausnahme.
> Vermutlich sind auch andere Ansätze denkbar.
Womit man bei jedem Aufruf einer Methode mit optionalen Parametern mit
einer "InconsistenVersioningException", oder wie auch immer man die
nennen will, rechnen müsste. Da verwende ich doch lieber Überladungen.
Denkbar wäre vielleicht ein Attribut für den Parameter, das den default
Parameter angibt, wodurch der Compiler halt jeden Aufruf mit Reflection
entsprechend vervollständigen müsste. Auch hier würde zusätzlicher
Aufwand (in Form von unnötiger Auslastung beim Einsatz von Reflection)
entstehen, der beim Überladen nicht gegeben ist.
grüße
Bernhard Huemer
[1]: http://msdn2.microsoft.com/de-de/library/system.io.file.open.aspx
> Übrigens bin ich auch der Meinung, dass C# lean&clean bleiben soll,
> wodurch ich auch eher skeptisch auf Features wie Extension Methods, etc... reagiere.
ich finde auch, die angekündigten '3.0' Features sollte man eher nur punktuell einsetzen
wo sie effektive Vorteile bringen.
Für mich ist C# 2.0 nahezu vollständig und optimal,
alles weitere sehe ich eher als nice-to-have Optionen...
> Übrigens bin ich auch der Meinung, dass C# lean&clean bleiben soll,
> wodurch ich auch eher skeptisch auf Features wie Extension Methods,
> etc... reagiere.
Extension Methods werden gebraucht, dass LINQ funktioniert. Nur durch
Extension Methods ist es z.B. Möglich einem Interface (in LINQ Fall
IEnumerable) eine Method inkl. Implementierung zu verpassen.
var processes =
from p in Process.GetProcesses()
where p.Responing == false
select p;
In diesem Fall wird die Methode "Where((p) => p.Responsing == false)" auf
Process.GetProcesses() ausgeführt. "Where" ist eine Extension Method von
IEnumerable.
Die Anwendbarkeit in eigenen Anwendungen sehe ich schon (eben z.B. um
Interfaces Methoden hinzuzufügen). Es besteht halt die grosse Gefahr, dass
der Einsatz ausartet, und jeder Entwickler sich die "fehlenden" 10 Methoden
zu System.Object und System.String auf diese Weise hinzufügt.
mfg GP
> Extension Methods werden gebraucht, dass LINQ funktioniert.
da wohl schon, aber für 'normalen' Code kaum.
LINQ sehe ich persönlich eher als 'Nische'...
> Es besteht halt die grosse Gefahr, dass
> der Einsatz ausartet, und jeder Entwickler sich die "fehlenden" 10 Methoden
> zu System.Object und System.String auf diese Weise hinzufügt.
allerdings,
jeder der solchen Code 'veröffentlicht' bekommt von mir eins aufs Dach....
> Extension Methods werden gebraucht, dass LINQ funktioniert. Nur durch
> Extension Methods ist es z.B. Möglich einem Interface (in LINQ Fall
> IEnumerable) eine Method inkl. Implementierung zu verpassen.
Mir war schon bewusst, dass Extension Methods für LINQ benötigt werden.
Es geht aber eben um die Frage ob LINQ wirklich unbedingt notwendig ist,
um somit eine Aufnahme in die Sprache zu rechtfertigen. Meiner Meinung
nach sollte man derartige C# 3.0 Erweiterungen lieber als Add-On zum
derzeitigen Stand verteilen, nachdem sie für die öffentliche
Schnittstelle einer Komponente unerheblich sind, also lediglich ein
Implementierungsdetail.
Natürlich kann man derartige Erweiterung auch einfach boykottieren,
allerdings läuft es mit dieser Einstellung irgendwann auf eine, wie
Thomas Scheidegger sagte 'überladene Chaoten-Sprache' hinaus.
Das ist halt lediglich meine persönliche Meinung zum Thema C# 3.0, aber
derartige Diskussionen weichen vom eigentlichen Theam ab.
grüße
Bernhard Huemer
File.Open(string fn, FileMode fm ) { .... }
schreibe, und eigentlich nichts weiter ppassiert, als dass ein
zusätzlicher Parameter mit einem für mich unsichtbaren Wert versorgt
wird, und dann die eigentlich Arbeitsfunktion aufgerufen wird.
NAch Studium der obigen Deklaration
1.) weiß ich nicht, dass ein solcher Parameter existiert
2.) und wenn ich'S weiß, kenne ich den in 99% aller Fälle vernünftigen
Wert nicht.
Das das Programm *automatisch* diesen Wert zufügt, und mit einem zu 99%
vernünftigen Wert vorbesetzt, --- das ist für mich MAGIC.
Aber jedem das Seine. Wir haben wahrscheinlich unterschiedliche
Vorstellungen davon, was ein Programmierer in einem Funktionskopf sehen
will, und was nicht.
>
>
> > Meinungen ändern sich, neue Erkenntnisse kommen dazu. Bei der Definition
> > von C# hat man sich bewußt gegen Generics entschieden.
>
> meinen Informationen zufolge, etwa Microsoft-Research (u.a. May 2001, .NET 1.0 war erst in Beta!)
> http://research.microsoft.com/projects/clrgen/
> hat Microsoft Generics durchaus schon _sehr_ früh auch immer in Erwägung gezogen,
> aber aus Prioritätsgründen noch nicht in der 1.x implementiert.
> Denn Generics setzen umfassenden Support in der CLR-Runtime, JITer und Frameworklassen voraus.
>
> Auf Default-Params dagegen scheint mir viel bewusster verzichtet worden....
OK; das stimmt in der Tat. Das Beispiel mit den Generics war nicht
optimal gewählt. Dann nehmen wir eben Operator Overloading. Die Sprache
wäre sicher mehr lean und clean, wenn es das nicht gäbe. Denn funktional
brings OL nichts dazu, es ist lediglich "syntactic sugar", wie es
Stroustrup einmal treffend formulierte. Trotzdem ist es drin. Nach
deiner Vorstellung dürfte dsas Feature nicht drin sein. Hast du eine
Erklärung dafür? Ich schon.
> > > C# ist so oder so die erfolgreichste Sprache dieses Jahrtausends.
> > Bezweifle ich. Große Systeme werden nach wie vor in C++ geschrieben.
>
> C/C++: 1970/1983 = letztes Jahrtausend!
Du bist nicht informiert. Der C++ Standard wurde 1998 veröffentlicht und
2003 geringfügig angepasst (im Wesentlichen fehlerkorrigiert). Demnächst
steht die Version 2 des Standards an.
Wenn du dich darüber informieren möchtest, was gerade aktuell ist, schau
mal auf die Internetseite der JTC1/SC22/WG21, die bei der ISO/IEC die
für C++ zuständige Working Group ist.
www.open-std.org/jtc1/sc22/wg21/
Du wirst dich wundern, wie viele Aktivitäten dort sind. Ich befürchte
aber, dass du das meiste davon nicht verstehst. Zum Glück ist nicht
alles lean&clean, sondern es gibt auch noch Werkzeuge für Profis.
> > mit C++/CLI besser bedient
>
> nein, macht nur übergangsweise bei Technologie-Mixturen Sinn.
> (und C++/CLI kommt eh zu spät)
>
Ist mal wieder Ansichtssache. Allerdings behaupte ich, das Systeme mit
so ab 10e5 loc mit C# aus vielfältigen Gründen nicht mehr zu handeln sind.
Paule
Und genau hier geht für mich der Irrtum los. Dokumentation kann nicht
die Defizite einer Sprache beheben. Anders herum: Wenn ich Doku brauche,
um programmieren zu können, ist was falsch.
Ich möchte es gerne dem Funktionskopf ansehen, was Sache ist. Externe
Systeme wie Dokumentation, Intellisense, Folding Editors sollen helfen,
dürfen aber nicht Voraussetzung sein, dass man überhaupt arbeiten kann.
[snip]
>
> Natürlich muss die Schnittstelle konstant bleiben, aber aufgrund der
> "hard-codierten" default Parameter /kann/ sie das bei Veränderungen
> von optionalen Parametern nicht. Bei Überladungen ist das nicht der
> Fall sofern man nicht einen, ich sag einfach mal "soft" Breaking
> Change, der die Dokumentation "verletzt", einbaut.
JEtzt mal ehrlich, wo ist denn der Unterschied zwischen
f( int i = -1 ) { ... }
und
f ( int i ) { ... }
f ()
{
f( -1 );
}
In beiden Fällen ist der Vorgabewert "fest verdrahtet". Die Situation,
dass man im zweiten Falle nicht auf -1 festgelegt ist, sondern hier
prinzipiell auch eine VAriable verwenden kann, ist mir in der Praxis
noch nie vorgekommen.
In der Tat müssen im ersten Fall alle clienten von f recompiliert
werden, wenn sich der Vorgabewert ändert. Das ist aber MEchanik und
kostet keinen Denkaufwand, ist somit zu verschmerzen. Der Vorteil der
Lösung 2 diesbezüglich ist also nicht relevant.
>>> Übrigens bin ich auch der Meinung, dass C# lean&clean bleiben soll,
>>> wodurch ich auch eher skeptisch auf Features wie Extension Methods,
>>> etc... reagiere.
>>
>> Auch ich stehe derartigen Erweiterungen teils kritisch gegenüber.
>>
Man muss immer den Nutzen eines Sprachmittels gegenüber den Kosten
sehen. Die Kosten der fehlenden Default Parameter sind erheblich, was
sich in unnötiger Codemenge und Komplexität äußert.
Die Erfinder der Extension Methods hat wahrscheinlich der Teufel
geritten - bzw. ich kann mir schon vorstellen, was da abgelaufen ist.
Gerade hier kann man IMHO gut erkennen, was beim Sprachdesign so abgeht.
Das hehre Prinzip einer klaren, sauberen Sprache war's hier sicher
nicht. Und wenn wir mal an die Segnungen der Version 3 denken ---- schauder!
Grüße - Paule
[weitere, für Normalsterbliche völlig unverständliche Erläuterungen
gesnippt]
Mit LINQ verlässt C# den Weg einer Arbeitssprache, die auch für einfach
gestrickte Programmierer verständlich ist. Ich denke, dies wird der
Sache eher schaden.
AUch ich denke, dass irgendwo eine Grenze definiert werden soll, die von
der Sprachkomplexität nicht überschritten werden soll, damit die Sprache
für das Heer der Normalos handhabbar bleibt.
Grüße - Paul
du meinst irgend eine ANSI/ISO C++ Norm.
Stroustrup 1983 : http://en.wikipedia.org/wiki/C%2B%2B
Und viele namhafte C++ Compiler gabs lange vor 1998.
(Visual C++ http://en.wikipedia.org/wiki/Microsoft_C )
Ich persönlich nutzte seinerzeit C seit ~1986
und kaufte zB Microsoft Visual C++ 2.0 im Jahr 1995.
Wer ist da wohl nicht informiert?
> Operator Overloading
O.O. ist sicherlich nicht sehr notwenig und in C# eh recht 'eingeschränkt'.
Schon Eric Gunnerson hat ~2001 im allerersten Buch für C# dazu geschrieben:
"...be used only when necessary...." und etliche ähnliche 'Ermahnungen'.
Wird wenn überhaupt dann AFAIK wohl primär für (in)equality == != angewendet.
Mal eine Zwischenfrage, willst du hier jetzt ernsthaft alle (angeblich fehlenden/zuviele) Features von C# durchgehen?
Dann kommst du aber 5 Jahre zu spät!
> www.open-std.org/jtc1/sc22/wg21/
> Du wirst dich wundern, wie viele Aktivitäten dort sind.
als ob dies was heissen würde... (zuviele Interessengruppen beim Machtspielchen)
> Ich befürchte aber, dass du das meiste davon nicht verstehst
Wie kommst du darauf? ich kannte C/C++ bis ~2002 sehr gut.
Und alle Zusatz-Bastlereien seither an C++ werden die Sache kaum mehr verbessern/retten.
> Ist mal wieder Ansichtssache. Allerdings behaupte ich, das Systeme mit
> so ab 10e5 loc mit C# aus vielfältigen Gründen nicht mehr zu handeln sind.
dir fehlt ganz offensichtlich die Erfahrung (und das Know How)....
Ich habe dann ein anderes Sprachfeature gebracht, nämlich O.O. Hier
müssten die gleichen Argumente ebenfalls gelten. Interessanterweise
akzeptierst du O.O. während du Default-Args ablehnst. Aus
sprachtheoretischer Sicht für mich nicht nachvollziehbar.
Ich bin gerne bereit, über das Thema zu diskutieren, weil ich vielleicht
noch was lernen kann, und nicht, um dir meine Meinung aufzudrängen. Dazu
musst du aber beim Thema bleiben und sinnvolle Argumente bringen. Dein
Beitrag oben in diesem Posting ist keines von beiden. Wenn du nichts
Tiefergehendes zu sagen hast, sollten wir hier abbrechen.
>
> Mal eine Zwischenfrage, willst du hier jetzt ernsthaft alle (angeblich fehlenden/zuviele) Features von C# durchgehen?
> Dann kommst du aber 5 Jahre zu spät!
>
Nein, Ich habe ein Beispiel gebracht für ein Sprachmittel, das ebenfalls
funktional nichts bringt, aber trotzdem allgemein akzeptiert ist.
Ich äußere mich hier nicht zu fehlenden oder überflüssigen
Sprachfeatures - ich gebe lediglich ein Beispiel zu meiner
Argumentation, dass "lean&mean" kein Argument für oder gegen ein
Sprachfeature sein sollte.
> > www.open-std.org/jtc1/sc22/wg21/
> > Du wirst dich wundern, wie viele Aktivitäten dort sind.
>
> als ob dies was heissen würde... (zuviele Interessengruppen beim Machtspielchen)
Ich möchte nicht beurteilen, ob das was heißt. Es reicht, wenn dies die
global player im Markt tun.
Im übrigen ging es hier darum, dass du sagtest:
> C/C++: 1970/1983 = letztes Jahrtausend!
Ich habe dir lediglich Informationen gegeben, diese Irrmeinung zu
korrigieren.
> > Ich befürchte aber, dass du das meiste davon nicht verstehst
>
> Wie kommst du darauf? ich kannte C/C++ bis ~2002 sehr gut.
> Und alle Zusatz-Bastlereien seither an C++ werden die Sache kaum mehr verbessern/retten.
>
Wenn du dich bis 2002 mit C++ befasst hast, aber gleichzeitig den
Sprachstand von 1983 verwendest, verstehe ich natürlich alles besser. Du
solltest dich dann aber ein Wenig mit Aussagen zu C++ zurückhalten.
> > Ist mal wieder Ansichtssache. Allerdings behaupte ich, das Systeme mit
> > so ab 10e5 loc mit C# aus vielfältigen Gründen nicht mehr zu handeln sind.
>
> dir fehlt ganz offensichtlich die Erfahrung (und das Know How)....
>
Gut möglich. Ich bin erst 50 Jahre alt und habe erst 25 Jahre Erfahrung
als freiberuflicher Consultant. In dieser Zeit habe ich mit
Unternehmensberatung zu IT-Fragen mein Geld verdent, zwei Firmen
gegründet, einige Bücher geschrieben und zahllose Projekte begleitet.
Vielleicht möchtest du dich ebenfalls outen?
Grüße - Paul
> Und genau hier geht für mich der Irrtum los. Dokumentation kann nicht
> die Defizite einer Sprache beheben. Anders herum: Wenn ich Doku
> brauche, um programmieren zu können, ist was falsch.
Dann sag mir doch ohne Dokumentation, IntelliSense, etc.. was der
default Wert für diesen oder jenen optionalen Parameter ist?
> Die Situation, dass man im zweiten Falle nicht auf -1 festgelegt ist,
> sondern hier prinzipiell auch eine VAriable verwenden kann, ist mir
> in der Praxis noch nie vorgekommen.
Dann geb ich dir einfach ein Beispiel, deins. Sieh dir einfach mal
File.Open(string, FileMode) mit dem Reflector an:
public static FileStream Open(string path, FileMode mode)
{
return File.Open(path, mode,
(mode == FileMode.Append) ?
FileAccess.Write : FileAccess.ReadWrite, FileShare.None);
}
Überladungen bieten ganz klar mehr Flexibilität mit geringerer Kopplung,
da man ja nicht gezwungen eine andere Überladung aufzurufen sondern auch
ganz andere Methoden aufrufen kann. Ich denke dabei z.B: an Fälle in
denen eine Überladung als deprecated markiert wird und eine Alternative
benutzt werden soll. Die default Überladung, also jene, die eigentlich
den default Parameter übergibt, kann ohne Weiteres auf die Alternative
umgestellt werden und muss somit nicht auch deprecated erklärt werden.
Bei optionalen Parametern wäre dies nicht möglich gewesen, da hier 2
Methoden als eine "verkauft" werden.
> In der Tat müssen im ersten Fall alle clienten von f recompiliert
> werden, wenn sich der Vorgabewert ändert. Das ist aber MEchanik und
> kostet keinen Denkaufwand, ist somit zu verschmerzen. Der Vorteil der
> Lösung 2 diesbezüglich ist also nicht relevant.
Dann müsste ich allerdings die gesamte Anwendung neu ausliefern, wenn
ich doch nur einen Patch ausliefern wollte ..
Wie du schon sagtest, man muss den Nutzen eines Sprachmittels in Bezug
auf die Kosten sehen und wenn ich mir durch optionale Parameter
Continous Builds, etc.. verbaue, dann ist das nicht tragbar.
grüße
Bernhard Huemer
Nochmals:
C/C++ ist eben im letzten Jahrtausend erschienen, C# in diesem,
dazwischen liegt eine ganze Generation.
Ist das so schwer zu begreifen?
> Sprachstand von 1983 verwendest
davon habe ich nie gesprochen, offenbar willst du hier nur provozieren...
> einige Bücher geschrieben....
> Vielleicht möchtest du dich ebenfalls outen?
weder Google noch Amazon kennen einen Autor 'Werkowitz'...
Vermutung: du schwindelst also entweder so (Buch) oder so (Pseudonym) etwas?
Grundsatzfrage:
was suchst du eigentlich genau in einer C# Newsgroup,
wenn C# angeblich so 'schlecht' und C++ so viel besser ist?
Ich habe jetzt diese Diskussion sehr interessiert verfolgt. Ich komme auch
aus der VB(A)-Welt, bin aber von C# ziemlich restlos begeistert (bin noch
Newbie!), da ich hier endlich so OOP programmieren kann, wie ich das in VB
immer schon gemacht habe / machen wollte (dort halt mit einigen
Klimmzügen).
Zu den optionalen Parametern:
Der Streit scheint sich ja daran zu entzünden, dass bei optionalen
Parametern der Kompiler die optionalen Werte in den *Nutz*-Code
hinein-"mogelt", während bei C# die optionalen Werte - genauso hard coded!
- in der Implementierung der Komponente selbst verbleiben.
Klar, mit C# sorgt eine Änderung der Komponente dafür, dass ein diese
Komponente *nutzender* Code sofort mit den geänderten Werten arbeitet. Aber
will ich denn das?
Als Programmierer, der eine Komponente nutzt, erwarte ich, dass sie sich
morgen genau so verhält wie gestern. Wurden die optionalen Werte in den
*nutzenden* Code hinein kompiliert, dann wird die Komponente morgen das
selbe Verhalten haben wie gestern, sogar wenn dort ein anderer Default-Wert
eingetragen sein sollte, nicht so bei einer Änderungen der Implementierung
der Komponente selbst...
Sollte ich hier etwas grundsätzlich falsch verstanden haben, bitte ich um
Aufklärung.
... und dass eine veröffentlichte Komponente ihre öffentliche
Schnittstelle(n) nur noch erweitern darf, ist ohnehin klar!
Und noch etwas: Die optionalen Parameter in VB entwickeln ihren Charme ja
erst in Verbindung mit den "benannten Parametern" so richtig. Der Code wird
dadurch viel(!!!) lesbarer.
Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung mit
allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder Code in
Büchern lese. Welche der Überladungen mit 4 Parametern gerade verwendet
wird ist dann schon recht schwer zu erkennen...
just my 2 cents...
lg
Gottfried
--
Home: www.develes.net
Mail: gol /at/ develes /dot/ net
Access-FAQ: www.donkarl.com
> Als Programmierer, der eine Komponente nutzt, erwarte ich, dass sie
> sich morgen genau so verhält wie gestern. Wurden die optionalen Werte
> in den *nutzenden* Code hinein kompiliert, dann wird die Komponente
> morgen das selbe Verhalten haben wie gestern, sogar wenn dort ein
> anderer Default-Wert eingetragen sein sollte, nicht so bei einer
> Änderungen der Implementierung der Komponente selbst...
Natürlich werden sich die Komponenten weiterhin so verhalten, wie
bisher, allerdings kann es dadurch zu Integrationsproblemen mit weiteren
Komponenten führen. Dazu folgendes, wie ich finde relativ einfaches,
Beispiel:
// FontUtils ermöglicht es anwendungsübergreifend
// eine gemeinsame Schriftart zu verwenden.
public class FontUtils {
public static Font CreateFont(float size = /* .. */) {
return new Font(/* .. */, size);
}
}
Entscheidet man sich nun dazu die Standardschrift zu vergrößern bekommt
man unweigerlich ein Problem wenn einige Assemblies neu übersetzt wurden
und andere nicht, denn dann werden verschiedene Standardschriften benutzt.
Zwar wirkt sich der Fehler in diesem Beispiel vielleicht nicht großartig
aus, aber dennoch lässt sich daran erkennen, dass Fehlerpotential
besteht.
> Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung
> mit allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder
> Code in Büchern lese. Welche der Überladungen mit 4 Parametern gerade
> verwendet wird ist dann schon recht schwer zu erkennen...
Die eingesetzten default Parameter lassen sich aber auch nicht unbedingt
leichter herauslesen ..
grüße
Bernhard Huemer
> > Als Programmierer, der eine Komponente nutzt, erwarte ich, dass sie
> > sich morgen genau so verhält wie gestern. [...]
>
> Natürlich werden sich die Komponenten weiterhin so verhalten, wie
> bisher, allerdings kann es dadurch zu Integrationsproblemen mit weiteren
> Komponenten führen. Dazu folgendes, wie ich finde relativ einfaches,
> Beispiel:
>
> [gesnippt]
Dein Beispiel zeigt deutlich, dass es Situationen gibt, wo man mit
optionalen Parametern (im Folgenden oP) auf Probleme stößt. Das sind dann
eben jene Fälle, wo man sie nicht verwenden sollte ;-) Für dein Beispiel
würde ich die Default-Schriftgröße in den Application-Settings o.ä.
unterbringen. Ich wäre hier nicht auf die Idee gekommen oP einzusetzen.
> > Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung
> > mit allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder
> > Code in Büchern lese. Welche der Überladungen mit 4 Parametern gerade
> > verwendet wird ist dann schon recht schwer zu erkennen...
>
> Die eingesetzten default Parameter lassen sich aber auch nicht unbedingt
> leichter herauslesen ..
Das ist wahr, in Kombination mit "benannten Parametern" (die ich in VB(A)
exzessiv einsetze) erhöht sich aber die Lesbarkeit enorm... (Zugegeben, das
hat mit oPs jetzt nur am Rande zu tun ;-) )
> Dein Beispiel zeigt deutlich, dass es Situationen gibt, wo man mit
> optionalen Parametern (im Folgenden oP) auf Probleme stößt. Das sind
> dann eben jene Fälle, wo man sie nicht verwenden sollte ;-) Für dein
> Beispiel würde ich die Default-Schriftgröße in den
> Application-Settings o.ä. unterbringen. Ich wäre hier nicht auf die
> Idee gekommen oP einzusetzen.
Natürlich macht nicht jeder derartige Fehler und verwendet von Beginn
an Konfigurationsdatein, aber solange die Fehlerquelle existiert werden
auch Fehler gemacht und das gilt es zu vermeiden. Es kann ja wohl nicht
der richtige Weg sein in der Sprache selbst Features anzubieten, die
bei falscher Verwendung zu Problemen bei der Integration einzelner
Teile der Anwendung führen können.
grüße
Bernhard Huemer
"Thomas Scheidegger [MVP]" <spam.ne...@swissonline.ch> schrieb:
>>> C/C++: 1970/1983 = letztes Jahrtausend!
>>
>> Ich habe dir lediglich Informationen gegeben, diese Irrmeinung zu
>> korrigieren.
>
> Nochmals:
> C/C++ ist eben im letzten Jahrtausend erschienen, C# in diesem,
> dazwischen liegt eine ganze Generation.
> Ist das so schwer zu begreifen?
Was bezweckst du denn mit dem Vergleich? C# und C (ich schreibe hier bewusst
nicht C++) sind wohl kaum vergleichbar, da sie zwei nicht überlappende
Zielgruppen und Anwendungsbereiche abdecken. Auch deine Beschränkung auf
dieses Jahrtausend ist rein beliebiger Natur und sagt überhaupt nichts über
die Qualität einer Programmiersprache aus.
>> einige Bücher geschrieben....
>> Vielleicht möchtest du dich ebenfalls outen?
>
> weder Google noch Amazon kennen einen Autor 'Werkowitz'...
> Vermutung: du schwindelst also entweder so (Buch) oder so (Pseudonym)
> etwas?
... oder das Buch wurde vor 20 Jahren veröffentlicht.
"Gottfried Lesigang" <gottfried...@web.de> schrieb:
> Der Streit scheint sich ja daran zu entzünden, dass bei optionalen
> Parametern der Kompiler die optionalen Werte in den *Nutz*-Code
> hinein-"mogelt", während bei C# die optionalen Werte - genauso hard coded!
> - in der Implementierung der Komponente selbst verbleiben.
Richtig erkannt.
> Klar, mit C# sorgt eine Änderung der Komponente dafür, dass ein diese
> Komponente *nutzender* Code sofort mit den geänderten Werten arbeitet.
> Aber
> will ich denn das?
Genau das ist die Frage. Ich sage: Nein, da in vielen Fällen selbst die an
eine parameterreichere Methode übergebenen Standardwerte Teil der
Zusicherungen sind, die Teil des Vertrags darstellen, den eine Methode
anbietet.
> Als Programmierer, der eine Komponente nutzt, erwarte ich, dass sie sich
> morgen genau so verhält wie gestern. Wurden die optionalen Werte in den
> *nutzenden* Code hinein kompiliert, dann wird die Komponente morgen das
> selbe Verhalten haben wie gestern, sogar wenn dort ein anderer
> Default-Wert
> eingetragen sein sollte, nicht so bei einer Änderungen der Implementierung
> der Komponente selbst...
Das stimmt. Dennoch halte ich es eben aus dem Grund für gefährlich,
Standardparameterwerte zu ändern (damit schliesse ich auch die an
parameterreichere Überladungen innerhalb der Implementierung übergebenen
Werte ein), da sich spätestens beim erneuten Kompilieren das Verhalten
ändert.
> ... und dass eine veröffentlichte Komponente ihre öffentliche
> Schnittstelle(n) nur noch erweitern darf, ist ohnehin klar!
Das scheint vielen hier leider nicht klar zu sein. Deshalb kritisiere ich ja
Eric Gunnersons ausführungen als rein theoretischer Natur, da in
professioneller Entwicklungspraxis eine Änderung an Schnittstellen
(einschliesslich Standardwerten für optionale Parameter etc.) ohnehin nicht
vorkommen.
> Und noch etwas: Die optionalen Parameter in VB entwickeln ihren Charme ja
> erst in Verbindung mit den "benannten Parametern" so richtig. Der Code
> wird
> dadurch viel(!!!) lesbarer.
Dem stimme ich zu.
> Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung mit
> allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder Code in
> Büchern lese. Welche der Überladungen mit 4 Parametern gerade verwendet
> wird ist dann schon recht schwer zu erkennen...
Das typische Überladungsdilemma.
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > Als Programmierer, der eine Komponente nutzt, erwarte ich, dass sie
> > sich morgen genau so verhält wie gestern. Wurden die optionalen Werte
> > in den *nutzenden* Code hinein kompiliert, dann wird die Komponente
> > morgen das selbe Verhalten haben wie gestern, sogar wenn dort ein
> > anderer Default-Wert eingetragen sein sollte, nicht so bei einer
> > Änderungen der Implementierung der Komponente selbst...
>
> Natürlich werden sich die Komponenten weiterhin so verhalten, wie
> bisher, allerdings kann es dadurch zu Integrationsproblemen mit weiteren
> Komponenten führen. Dazu folgendes, wie ich finde relativ einfaches,
> Beispiel:
>
> // FontUtils ermöglicht es anwendungsübergreifend
> // eine gemeinsame Schriftart zu verwenden.
> public class FontUtils {
>
> public static Font CreateFont(float size = /* .. */) {
> return new Font(/* .. */, size);
> }
> }
>
> Entscheidet man sich nun dazu die Standardschrift zu vergrößern bekommt
> man unweigerlich ein Problem wenn einige Assemblies neu übersetzt wurden
> und andere nicht, denn dann werden verschiedene Standardschriften benutzt.
Beachte: Wenn du in deinem Code den Wert einer in einer Bibliothek
definierten Konstante benutzt, wird dieser ebenfalls in deiner Assembly als
Kopie hinterlegt. Eine Änderung des Konstantenwertes in der Bibliothek hätte
ähnliche Folgen wie die Verwendung von Standardparametern. Die Definition
öffentlicher Konstanten wird aber von C# unterstützt! Werden nur einige
abhängige Bibliotheken neu übersetzt, führt dies ebenfalls zu den genannten
Problemen.
Konsequenz daraus kann nur sein, nichts an veröffentlichten Schnittstellen
zu verändern. Diese Vorgangsweise ist seit Jahrzehnten in der
Softwareentwicklung gängige Praxis und in manchen Fällen die einzige saubere
Lösung.
> > Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung
> > mit allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder
> > Code in Büchern lese. Welche der Überladungen mit 4 Parametern gerade
> > verwendet wird ist dann schon recht schwer zu erkennen...
>
> Die eingesetzten default Parameter lassen sich aber auch nicht unbedingt
> leichter herauslesen ..
Schon einmal VB.NET benutzt?
Nein, nicht schwer zu begreifen, und die Aussage ist auch korrekt.
Les dein diesbezügliches Posting nochmal. Ich denke schon, dass du genau
das sagen wolltest, was ich interpretiert habe.
>
> > Sprachstand von 1983 verwendest
>
> davon habe ich nie gesprochen, offenbar willst du hier nur provozieren...
OK; ich denke, das wars jetzt. Ich beende die "Diskussion". Leider ist
das eigentliche Thema immer noch unbeantwortet: warum Default-Params
schlecht sind. Leider immer noch keine stichhaltigen Args - außer der
Gunnerson-Meinung - IMHO kannst du halt auch keine geben.
> > einige Bücher geschrieben....
> > Vielleicht möchtest du dich ebenfalls outen?
>
> weder Google noch Amazon kennen einen Autor 'Werkowitz'...
> Vermutung: du schwindelst also entweder so (Buch) oder so (Pseudonym) etwas?
Paul Werkowitz ist meine NNTP Identität. Ein Pseudonym sozusagen. Ob du
mir meine Aussagen glaubst oder nicht, ist mir ziemlich wurscht. Ich
habe es nur gebracht wg. dem Vorwurf "keine Ahnung haben". Ich denke,
wenn jemand solche Sachen aus der Erfahrung heraus beurteilen kann, dann
ich.
>
> Grundsatzfrage:
> was suchst du eigentlich genau in einer C# Newsgroup,
> wenn C# angeblich so 'schlecht' und C++ so viel besser ist?
>
OK; ich denke, jetzt reichts. Mir zumindest.
Diese Aussage habe ich nie gemacht. Es ging mir lediglich um die
Default-Argumente, die ich für sehr gut halte, und die C++ nun mal eben
hat, und C# nicht. Ich wollte eigentlich Argumente dagegen hören, die
über die eigentlich unhaltbare Gunnerson-Meinung hinausgehen.
Ich erinnere mich an eine Situation aus meiner Jugend, in der ich es
gewagt hatte, eine positive Eigenschaft der damaligen DDR zu erwähnen.
Reaktion: Dann geh doch rüber und lebe dort, wenn dir's dort so viel
besser gefällt.
Es bleibt weiterhin offen, welche Erfahrung du bereits vorweisen kannst.
Du möchtest dich sicher ebenfalls outen, damit wir sehen können,
welche Erfahrungen du in der IT schon gesammelt hast.
Grüße - Paule
> // FontUtils ermöglicht es anwendungsübergreifend
> // eine gemeinsame Schriftart zu verwenden.
> public class FontUtils {
>
> public static Font CreateFont(float size = /* .. */) {
> return new Font(/* .. */, size);
> }
> }
>
> Entscheidet man sich nun dazu die Standardschrift zu vergrößern bekommt
> man unweigerlich ein Problem wenn einige Assemblies neu übersetzt wurden
> und andere nicht, denn dann werden verschiedene Standardschriften benutzt.
>
OK; du meinst also du hast
public static Font CreateFont(float size = 12 ) { ... }
und änderst das auf
public static Font CreateFont(float size = 16 ) { ... }
Nun müssen alle clienten von CreateFont neu kompiliert werden. Ein
vernünftiger Build-Magaer wird das auch so veranlassen.
Die Situation ist genau so, als wenn du
f ( int i ) { ... }
auf
f( double d ) { ... }
veränderst. Dann wirst du doch sicher auch nicht nur die Hälfe deiner
clienten von f neu compilieren?
>
> > Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung
> > mit allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder
> > Code in Büchern lese. Welche der Überladungen mit 4 Parametern gerade
> > verwendet wird ist dann schon recht schwer zu erkennen...
>
> Die eingesetzten default Parameter lassen sich aber auch nicht unbedingt
> leichter herauslesen ..
>
Hmmm. Wenn ich
f ( int i = -1 )
schreibe, ist das für mich glasklar. Ich muss die -1 nicht irgendwo in
einer Implementierung suchen.
Grüße - Paule
> Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung mit
> allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder Code in
> Büchern lese. Welche der Überladungen mit 4 Parametern gerade verwendet
> wird ist dann schon recht schwer zu erkennen...
>
Was ich immer schon sage: eine Sprache sollte auch ohne externe
Hilfsmittel wie Intellisense oder automatischen Doku-Generatoren
verwendbar sein. Durch Default-Parameter wäre dies leichter.
Paule
> Beachte: Wenn du in deinem Code den Wert einer in einer Bibliothek
> definierten Konstante benutzt, wird dieser ebenfalls in deiner
> Assembly als Kopie hinterlegt. Eine Änderung des Konstantenwertes
> in der Bibliothek hätte ähnliche Folgen wie die Verwendung von
> Standardparametern.
Ehrlich gesagt habe ich noch nicht erlebt das für andere Konstanten,
als jene die mit der WinApi zusammenhängen, der const Modifzierer
statt readonly verwendet wird.
> Konsequenz daraus kann nur sein, nichts an veröffentlichten
> Schnittstellen zu verändern. Diese Vorgangsweise ist seit Jahrzehnten
> in der Softwareentwicklung gängige Praxis und in manchen Fällen die
> einzige saubere Lösung.
Warum sollte man es überhaupt soweit kommen lassen? Das Problem an
optionalen Parametern ist eben, dass die Standard Parameter zur
öffentlichen Schnittstelle gehören, während dieser Wert in
Überladungen lediglich ein Implementierungsdetail ist.
> Schon einmal VB.NET benutzt?
--
Public Shared Sub Print(Optional ByVal message As String = "foo")
Console.WriteLine(message)
End Sub
Public Shared Sub Main()
' Ich seh hier und demzufolge auch in keinem Buch, Artikel
' oder sonstigem Printmedium den Standard Parameter
Print()
End Sub
--
grüße
Bernhard Huemer
damit ist deine Glaubwürdigkeit restlos dahin.
(insbesondere nach derart geschwollenen Reden)
Und formell dazu noch dies:
http://support.microsoft.com/gp/ngnetikette/de
"Verwenden Sie beim Posten in den Newsgroups keinen chatüblichen Nickname.
Mit einem Realnamen ..."
das problem ist schlicht, dass ersteres ueberhaupt nicht auffallen
muss bis es kracht. etwas anderes wäre es, wenn bspweise defaultparams
ueber eine art intellisense seitens der ide beim programmieren
eingefügt würden. das würde sinn machen, aber natürlich auch nicht bei
fetten/kranken schnittstellen mit dutzenden von defaults.
defaults sind anfangs praktisch, aber in der folge sehr gefährlich.
gleiches gilt für makros, die ich bspweise in c# vermisse
"Thomas Scheidegger [MVP]" <spam.ne...@swissonline.ch> schrieb:
>> Paul Werkowitz ist meine NNTP Identität. Ein Pseudonym sozusagen.
>
> damit ist deine Glaubwürdigkeit restlos dahin.
> (insbesondere nach derart geschwollenen Reden)
Interessant: Hat man keine Argumente dagegenzusetzen, diskreditiert man die
Person.
> Und formell dazu noch dies:
> http://support.microsoft.com/gp/ngnetikette/de
>
> "Verwenden Sie beim Posten in den Newsgroups keinen chatüblichen
> Nickname.
> Mit einem Realnamen ..."
"Paul Werkowitz" /ist/ ein Realname ("Vorname Nachname").
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > Beachte: Wenn du in deinem Code den Wert einer in einer Bibliothek
> > definierten Konstante benutzt, wird dieser ebenfalls in deiner
> > Assembly als Kopie hinterlegt. Eine Änderung des Konstantenwertes
> > in der Bibliothek hätte ähnliche Folgen wie die Verwendung von
> > Standardparametern.
>
> Ehrlich gesagt habe ich noch nicht erlebt das für andere Konstanten,
> als jene die mit der WinApi zusammenhängen, der const Modifzierer
> statt readonly verwendet wird.
Theoretisch besteht aber die Möglichkeit. Eine Konstante ist eben semantisch
nicht äquivalent zu einer 'ReadOnly'-Variablen oder -Eigenschaft. Konstanten
haben, ebenso wie Standardparameter, etwas endgültiges.
> > Konsequenz daraus kann nur sein, nichts an veröffentlichten
> > Schnittstellen zu verändern. Diese Vorgangsweise ist seit Jahrzehnten
> > in der Softwareentwicklung gängige Praxis und in manchen Fällen die
> > einzige saubere Lösung.
>
> Warum sollte man es überhaupt soweit kommen lassen? Das Problem an
> optionalen Parametern ist eben, dass die Standard Parameter zur
> öffentlichen Schnittstelle gehören, während dieser Wert in
> Überladungen lediglich ein Implementierungsdetail ist.
Hier hat Paul das Beispiel der Dateizugriffsmethoden gebracht, wo bei
Überladungen unzulässigerweise Informationen versteckt werden, obwohl diese
für die Verwendung der Methode von Bedeutung sind. Noch einmal: Ich
propagiere nicht die Verwendung optionaler Parameter in Situationen, in
denen dies nicht der Fall ist.
> > Schon einmal VB.NET benutzt?
>
> --
> Public Shared Sub Print(Optional ByVal message As String = "foo")
> Console.WriteLine(message)
> End Sub
>
> Public Shared Sub Main()
> ' Ich seh hier und demzufolge auch in keinem Buch, Artikel
> ' oder sonstigem Printmedium den Standard Parameter
> Print()
> End Sub
Bewege den Mauszeiger über den 'Print()'-Aufruf. Im Hinweistext erscheint
"Public Shared Sub Print([Message As String = "foo"])".
Wieso must du meinen real life namen kennen, um dich mit meinen
Argumenten auseinandersetzen zu können?
> Und formell dazu noch dies:
> http://support.microsoft.com/gp/ngnetikette/de
>
> "Verwenden Sie beim Posten in den Newsgroups keinen chatüblichen Nickname.
> Mit einem Realnamen ..."
>
Du hälst dich offensichtlich zu wenig in chats auf, um zu wissen, was
ein nick ist. "Paul Werkowitz" ist definitiv keiner....
Paule
"jan rosinowski" <spamf...@rsp.de> schrieb:
> defaults sind anfangs praktisch, aber in der folge sehr gefährlich.
> gleiches gilt für makros, die ich bspweise in c# vermisse
Nein, sie sind absolut nicht gefährlich! Nicht gefährlicher, als das
Schreiben jeglichen Quellcodes. Sie sind bestenfalls dann gefährlich, wenn
du mit 2.0 Promille Alkohol im Blut Änderungen an den Standardwerten
vornimmst. Von selbst verändern sich die Standardwerte ja nicht.
> OK; du meinst also du hast
>
> public static Font CreateFont(float size = 12 ) { ... }
>
> und änderst das auf
>
> public static Font CreateFont(float size = 16 ) { ... }
>
> Nun müssen alle clienten von CreateFont neu kompiliert werden. Ein
> vernünftiger Build-Magaer wird das auch so veranlassen.
Wenn man optionale Parameter mit Überladungen gleichsetzt, muss man
in diesem Beispiel zuerst mal davon ausgehen, dass eine Änderung des
Standard Parameters keine Veränderung der öffentlichen Schnittstelle
beinhaltet, denn bei Überladungen ist das ja nicht der Fall.
Egal ob Build-Manager oder nicht, wird ersichtlich, dass optionale
Parameter als reines nice-to-have Feature in den Build Prozess
eingreifen. Zusätzlicher Aufwand besteht für einen Build Manager,
da er derartige Änderungen des Standard Parameters registrieren
muss. Alles in allem Aufwand, der ein nice-to-have Feature nicht
rechtfertigt.
> Die Situation ist genau so, als wenn du
>
> f ( int i ) { ... }
>
> auf
>
> f( double d ) { ... }
>
> veränderst. Dann wirst du doch sicher auch nicht nur die Hälfe deiner
> clienten von f neu compilieren?
Das kann man nicht miteinander vergleichen, denn in diesem Fall würde
mit einer MissingMethodException entsprechend reagiert werden, wenn
man nicht neu kompiliert.
> Wenn ich Doku brauche, um programmieren zu können, ist was falsch.
Um diese Aussage etwas anzupassen:
Wenn ich Tools wie einen Build Manager brauche, um programmieren zu
können, ist was falsch.
grüße
Bernhard Huemer
du hast deine Glaubwürdigkeit hier eh schon längst verspielt....
Und führ die dümmliche VB-Petitions-Sig mal dem GC zu.
Wieso fällt das nicht auf? Wenn ich eine Funktionsdeklaration ändere,
werden clienten neu kompiliert. Das gilt auch, wenn ich 12 auf 16
ändere. Wo ist das Problem?
Paule
> Theoretisch besteht aber die Möglichkeit. Eine Konstante ist eben
> semantisch nicht äquivalent zu einer 'ReadOnly'-Variablen oder
> -Eigenschaft. Konstanten haben, ebenso wie Standardparameter, etwas
> endgültiges.
Irgendwie klingt das für mich als würdest du sagen, dass man den Fehler
ohnehin bereits mit Konstanten machen kann, warum also nicht auch noch
mit optionalen Parametern. Auch wenn du das nicht so meinst, aber es
läuft darauf hinaus.
> Hier hat Paul das Beispiel der Dateizugriffsmethoden gebracht, wo bei
> Überladungen unzulässigerweise Informationen versteckt werden, obwohl
> diese für die Verwendung der Methode von Bedeutung sind.
Pauls Beispiel wurde meiner Meinung nach widerlegt durch die Tatsache,
dass File.Open(string, FileMode) mit optionalen Parametern nicht
realisierbar wäre, da ein Standard Parameter variabel ist.
Selbst wenn der Standard Parameter anfangs konstant ist, verbaut man
sich mit optionalen Parametern nur die Möglichkeit diesen Standard
Parameter im Laufe von Änderungen variabel zu ermitteln.
Um es also nochmal klarzustellen: Der geringere Schreibaufwand
rechtfertigt nicht den Verlust an Flexibilität und geringerer Kopplung.
> Bewege den Mauszeiger über den 'Print()'-Aufruf. Im Hinweistext
> erscheint "Public Shared Sub Print([Message As String = "foo"])".
Wie bereits erwähnt, dreht es sich aber um Printmedien. Da könnt ich
ja genauso mit der Dokumentation argumentieren, die im Hinweisetext
erscheint.
> Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung
> mit allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder
> Code in Büchern lese.
grüße
Bernhard Huemer
Genau auf den Punkt gebracht. Nur ist es eben kein Problem, sondern ein
Feature.
Beispiel: Ich möchte nicht Code studieren müssen, um zu sehen, ob
jemand, der mir eine Bibliothek zuliefert, den Default eines parameters
geändert hat. Dies gehört sprachtheoretisch in die Funktionsdeklaration.
Selbstverständlich gibt es Situationen, wo das nicht passt. Dann muss
man eben andere Sprachmittel nehmen, z.B. Überladung. Was man jedoch
nicht machen sollte, und was hier in der NG eben häufig püassiert, ist
folgender Schluss: es gibt Situationen, für die sind Default-Parameter
nicht geeignet. Ergo: Dfault-Parameter sind schlecht. (und da C++ sie
hat, erst recht).
Im übrigen gilt (wie immer): Wenn ich eine Entkopplung wünsche, kann ich
eine zusätzliche Indirektionsstufe einziehen. Genau das *muss* ich aber
machen, wenn ich C# verwende. Auch wenn ichs nicht will.
Grüße - Paule
verstehe ich nicht. Was spricht gegen
File.Open(string fn, FileMode, FileAccess fa = FileAccess.ReadWrite)
{ ... }
>
> Selbst wenn der Standard Parameter anfangs konstant ist, verbaut man
> sich mit optionalen Parametern nur die Möglichkeit diesen Standard
> Parameter im Laufe von Änderungen variabel zu ermitteln.
>
Dies ist korrekt. Wie gesagt, nicht jede Aufgabenstellung wird durch
Vorgabewerte optimal gelöst. Wenn du eine solche Flexibilität benötigst,
sind Vorgabeparameter nicht das richtige Sprachmittel. Allerdings
erscheint mir die Notwendigkeit zu solcher Variablitität sehr selten
gegeben. Beim File.Open (sowie 100% der von mir bisher verwendeten Teile
der BCL) zumindest nicht.
Wichtig erscheint mir, dass Vorgabewerte eine Transition zu deinem
Szenario zulassen, ohne clienten zu behelligen. Man kann durchaus mit
void f( int i = -1 ) { ... }
beginnen. Stellt man später fest, dass man die -1 lieber doch variabel
hätte, kann man immer noch
void f()
{
f( irgendwas );
}
schreiben. Es besteht also keine Gefahr einer Sackgasse.
> Um es also nochmal klarzustellen: Der geringere Schreibaufwand
> rechtfertigt nicht den Verlust an Flexibilität und geringerer Kopplung.
Habs gerade oben gesagt: Flexibilität ist trotzdem gegeben. Kopplung ist
größer, das stimmt, spielt aber idR weniger eine Rolle, und tritt hinter
dem Komplexitätsargument zurück.
Paule
> Genau auf den Punkt gebracht. Nur ist es eben kein Problem, sondern
> ein Feature.
Bei Parametern nennt man einen Verstoß gegen Information Hiding also
"Feature"?
Sinngemäß ist es meiner Meinung nach absolut das gleiche als würdest
du ein öffentliches read-only Feld empfehlen, wenn in der Eigenschaft
letztendlich eh nichts anderes gemacht wird, als ein simples return.
Beides zieht den selben Effekt nach sich: Man verbaut sich Flexibilität,
die man unter Umständen im Nachhinein braucht.
> Selbstverständlich gibt es Situationen, wo das nicht passt. Dann muss
> man eben andere Sprachmittel nehmen, z.B. Überladung. Was man jedoch
> nicht machen sollte, und was hier in der NG eben häufig püassiert, ist
> folgender Schluss: es gibt Situationen, für die sind Default-Parameter
> nicht geeignet. Ergo: Dfault-Parameter sind schlecht. (und da C++ sie
> hat, erst recht).
Das Problem ist aber, dass sich die Situation im nachhinein ändern und
man bei optionalen Parametern aufgrund mangelnder Flexibilität nicht
mehr entsprechend darauf reagieren kann.
grüße
Bernhard Huemer
> verstehe ich nicht. Was spricht gegen
>
> File.Open(string fn, FileMode, FileAccess fa = FileAccess.ReadWrite)
> { ... }
Ganz einfach: Es ist nicht das selbe, wie die derzeitige Implementierung.
--
public static FileStream Open(string path, FileMode mode) {
return File.Open(path, mode,
(mode == FileMode.Append) ? FileAccess.Write :
FileAccess.ReadWrite, FileShare.None);
}
--
> Wichtig erscheint mir, dass Vorgabewerte eine Transition zu deinem
> Szenario zulassen, ohne clienten zu behelligen. Man kann durchaus mit
>
> void f( int i = -1 ) { ... }
>
> beginnen. Stellt man später fest, dass man die -1 lieber doch variabel
> hätte, kann man immer noch
>
> void f()
> {
> f( irgendwas );
> }
>
> schreiben. Es besteht also keine Gefahr einer Sackgasse.
Um diese Annahme mit den unmissverständlichen Worten eines Compilers zu
widerlegen:
Public Shared Sub f([i As Integer = -1])' and 'Public Shared Sub f()'
cannot overload each other because they differ only by optional
parameters.
Mal abgesehen davon, dass der Compiler nicht entscheiden kann, welche
Methode bei einem Aufruf von f() verwendet werden soll, gilt auch hier
wieder, dass es ungewünschte Ergebnisse nach sich ziehen kann, wenn man
nicht alle Assemblies neu kompiliert.
> Habs gerade oben gesagt: Flexibilität ist trotzdem gegeben. Kopplung
> ist größer, das stimmt, spielt aber idR weniger eine Rolle, und tritt
> hinter dem Komplexitätsargument zurück.
siehe oben
grüße
Bernhard Huemer
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > OK; du meinst also du hast
> >
> > public static Font CreateFont(float size = 12 ) { ... }
> >
> > und änderst das auf
> >
> > public static Font CreateFont(float size = 16 ) { ... }
> >
> > Nun müssen alle clienten von CreateFont neu kompiliert werden. Ein
> > vernünftiger Build-Magaer wird das auch so veranlassen.
>
> Wenn man optionale Parameter mit Überladungen gleichsetzt, muss man
> in diesem Beispiel zuerst mal davon ausgehen, dass eine Änderung des
> Standard Parameters keine Veränderung der öffentlichen Schnittstelle
> beinhaltet, denn bei Überladungen ist das ja nicht der Fall.
Man muss bei der Diskussion zwischen folgenden Einsatztypen von Überladungen
unterscheiden:
1. Überladen zum Transparentmachen irrelevanter Details in einigen
überladenen Methodenversionen und damit Reduktion der
Abhängigkeit zwischen zwei Komponenten.
2. Überladen zur Vereinfachung des Methodenaufrufs, obwohl
Kenntnis der übergebenen Werte von Bedeutung ist. Die in der
Überladung mit weniger Parametern an die parameterreichere
Methodenversion übergebenen Werte sind dokumentiert und
damit Teil der Schnittstelle.
Während Typ 1 für Ersatz durch optionale Parameter nicht geeignet ist,
bietet sich dieser bei Typ 2 an. So ist 'MsgBox' aus VB.NET dem
'MessageBox.Show' mit seinen 21 Überladungen in Sachen Benutzbarkeit
überlegen.
> Egal ob Build-Manager oder nicht, wird ersichtlich, dass optionale
> Parameter als reines nice-to-have Feature in den Build Prozess
> eingreifen. Zusätzlicher Aufwand besteht für einen Build Manager,
> da er derartige Änderungen des Standard Parameters registrieren
> muss. Alles in allem Aufwand, der ein nice-to-have Feature nicht
> rechtfertigt.
Hier muss ich widersprechen. Optionale Parameter würden meiner Ansicht nach
aufgrund ihrer Vorteile (bessere Benutzbarkeit, explizitere Schnittstelle,
Zusicherung nicht nur in der Dokumentation) durchaus den Aufwand für eine
zusätzliche Überprüfung durch den Compiler/CLR rechtfertigen.
> Wenn ich Tools wie einen Build Manager brauche, um programmieren zu
> können, ist was falsch.
Die brauche ich nicht, da im Normalfall Änderungen an den Standardwerten
optionaler Parameter ebenso häufig auftreten wie das Ändern von
Methodensignaturen etc., was eine Veränderung der Schnittstelle zur Folge
hätte.
Nein, nicht gleichsetzen! Überladene Methoden sind etwas aganz anderes
als Defaultparameter! Eine bestimmte Klasse von Problemen kann durch
beide gelöst werden, trotzdem unterscheiden sich die Features!
Ein wichtiger Unterschied ist z.B., dass der Wert des Default-Params
öffentlich ist, bei der Simulation durch überladene Funktionen aber
nicht. Wenn ich den Default-Parameter nicht öffentlich haben will, sind
Vorgabewerte nicht die richtige Lösung für mein Problem.
Aber bedenke: Du hast heute z.B. die Situation
File.Open(string fn, FileMode fm, FileAccess fa )
{
Open( fn, fm, FileAccess.ReadWrite);
}
und in deinem Code schreibst du andauernd
File.Open( "temp.txt", FileMode.Open )
weil du eben weißt, dass der Default-Param für Access ReadWrite ist.
Irgendwann in ferner Zukunft ändert jemand die Implementierung auf
File.Open(string fn, FileMode fm, FileAccess fa )
{
Open( fn, fm, FileAccess.Read );
}
Jetzt mal ganz unabhängig davon, dass durch diese Änderung deine clients
nicht automatisch neu compiliert werden, was bedeutet das für die
Semantik deines Programms?
Willst du wirklich Quellcode inspizieren, um feststellen zu können, ob
du recompilieren musst?
Willst du Quellcode inspizieren, um festzustellen, dass sich der
simulierte Default-Parameter geändert hat?
Ich weiß nicht .... ich denke, ich will das nicht. Deshalb will ich,
dass Vorgabewerte zur öffentlichen Schnittstelle gehören.
>
> Egal ob Build-Manager oder nicht, wird ersichtlich, dass optionale
> Parameter als reines nice-to-have Feature in den Build Prozess
> eingreifen. Zusätzlicher Aufwand besteht für einen Build Manager,
> da er derartige Änderungen des Standard Parameters registrieren
> muss. Alles in allem Aufwand, der ein nice-to-have Feature nicht
> rechtfertigt.
Sehe ich halt anders. Das oben dargestellte Szenario (Änderung des
Default-Wertes) rechtfertigt dies IMHO auch.
Hinzu kommt Folgendes: Prinzipiell sollte man Arbeit auf Tools
verlagern, wenns geht. Eine Vereinfachung des Programmiermodells
rechtfertigt idR erhöhte Komplexität in den Tools. Also: Um Überladungen
zum Zwecke der Simulation von Vorgabeparametern zu sparen, halte ich den
zusätzlichen Aufwand im Build-Tool für gerechtfertigt.
>
> > Die Situation ist genau so, als wenn du
> >
> > f ( int i ) { ... }
> >
> > auf
> >
> > f( double d ) { ... }
> >
> > veränderst. Dann wirst du doch sicher auch nicht nur die Hälfe deiner
> > clienten von f neu compilieren?
>
> Das kann man nicht miteinander vergleichen, denn in diesem Fall würde
> mit einer MissingMethodException entsprechend reagiert werden, wenn
> man nicht neu kompiliert.
Korrekt. Insofern sind die beiden Beispiele nicht ganz identisch. ICh
wollte damit nur klarmachen, dass eben recompiliert werden muss, wenn
man die Vorgabewerte ändert. Dies ist meist das gewünschte Verhalten.
>
> > Wenn ich Doku brauche, um programmieren zu können, ist was falsch.
>
> Um diese Aussage etwas anzupassen:
> Wenn ich Tools wie einen Build Manager brauche, um programmieren zu
> können, ist was falsch.
OK, gut gekontert. Genauer müsste man daher formulieren: "Wenn man durch
ein einfaches Sprachmittel die Benutzung externer Tools extrem
verringern kann, ist dies ein starkes Argument für das Sprachmittel".
Das erschien mir aber bisshen zu lang ... sowas liest normalerwise
keiner wirklich.
Grüße - Paule
> Natürlich werden sich die Komponenten weiterhin so verhalten, wie bisher
ja, ich sehe da auch weniger ein Problem mit 'Breaking Changes'
(=> sollten eh besser vermieden werden),
Ich finde es aber einen Vorteil von nur genau zwei _beabsichtigten_ Interpretations-Arten
bei Überladungen allgemein in C#, deutlich etwa am Bsp:
FileStream.FileStream( String, ......[ Int32 bufferSize ] )
wenn ich den 'bufferSize' weglasse,
so 'überlasse' ich _bewusst_ diesen für mich meist weniger wichtigen Parameter einzig der Zielmethode.
Diese wird dann (je nach Doku/Plattform/Memory usw) den geeigneten/optimalen Wert selber bestimmen
(zB einen kleineren Buffer unter dem Compact-Framework, viel grösser unter 64-Bit, o.ä.)
Ein Compiler mit Default-Arguments kann diesen Entscheid kaum so optimal/passend übernehmen,
sondern würde den Wert _immer_ blind auf den seinerzeit vorbestimmten Default fixieren.
Wenn ich andererseits den 'bufferSize' explizit beim Aufruf angebe,
dann erkläre & erwarte ich dadurch auch _bewusst_ (explizit im Source-Code)
ein entsprechendes Verhalten von der Zielmethode, auch in neueren Versionen, auf anderen Plattformen.
Ich entscheide also bewusst, was für mich wichtig (explizit) und was Nebensache ist,
es gibt keine Heimlichkeiten dazwischen im Compiler.
Ein ~ähnlicher~ Fall beim [kurzzeitigen] 'übersteuern' von anderweitig vorbestimmten Parametern
Int32.ToString( String ) // = NumberFormatInfo.CurrentInfo
Int32.ToString( String, IFormatProvider )
hier passen Default-Arguments schon gar nicht hin.
Neben diesen paar Interpretationen von Überladungen
sehe ich eben kaum Nutzen für zusätzlich auch noch Default-Arguments (brächte eher Verwirrung).
IMHO:
Eine API/Schnittstelle als 'Kontrakt' soll zwischen mir (vollständig sichtbar in meinem Source)
und der Zielmethode streng definiert sein,
aber nicht noch über eine versteckte Zusatzklausel im Compiler/generiertem Code.
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > Genau auf den Punkt gebracht. Nur ist es eben kein Problem, sondern
> > ein Feature.
>
> Bei Parametern nennt man einen Verstoß gegen Information Hiding also
> "Feature"?
Ein optionaler Parameter versteckt eben, anders als eine Überladung, in
welcher der Parameter nicht aufscheint, keine Information. Der Parameterwert
ist in der Entwicklungsumgebung bei Bedarf nachvollziehbar /und/
dokumentiert.
Schlechtes Beispiel für Überladungen sind die 'FileStream'-Konstruktoren.
Bei 'FileStream(IntPtr, FileAccess)' steht etwa in den "Remarks", welcher
Wert für 'FileShare' implizit verwendet wird: "'FileShare.Read' is the
default for those 'FileStream' constructors without a 'FileShare'
parameter". Dies ist in der Entwicklungsumgebung ohne Dokumentation nicht
nachvollziehbar -- die Wahrscheinlichkeit, dass es zur Laufzeit knallt, weil
der nicht ersichtliche Parameter gar nicht bedacht wurde, ist grösser. Bei
optionalen Parametern ist klar ersichtlich, welcher Wert übergeben wird.
> Sinngemäß ist es meiner Meinung nach absolut das gleiche als würdest
> du ein öffentliches read-only Feld empfehlen, wenn in der Eigenschaft
> letztendlich eh nichts anderes gemacht wird, als ein simples return.
>
> Beides zieht den selben Effekt nach sich: Man verbaut sich Flexibilität,
> die man unter Umständen im Nachhinein braucht.
Wenn die Flexibilität etwas am Verhalten ändert, dann muss ohnehin auf sie
verzichtet werden, um die Schnittstelle stabil zu halten. Warum dann nicht
gleich eine Lösung wählen, welche die Möglichkeit der Flexibilität nicht
bietet, andererseits aber Vorteile besitzt?
> > Selbstverständlich gibt es Situationen, wo das nicht passt. Dann muss
> > man eben andere Sprachmittel nehmen, z.B. Überladung. Was man jedoch
> > nicht machen sollte, und was hier in der NG eben häufig püassiert, ist
> > folgender Schluss: es gibt Situationen, für die sind Default-Parameter
> > nicht geeignet. Ergo: Dfault-Parameter sind schlecht. (und da C++ sie
> > hat, erst recht).
>
> Das Problem ist aber, dass sich die Situation im nachhinein ändern und
> man bei optionalen Parametern aufgrund mangelnder Flexibilität nicht
> mehr entsprechend darauf reagieren kann.
Eine Änderung der Situation bedeutet neue Methoden/Schnittstellen, nicht
aber das Ändern des Verhaltens bestehender Methoden.
> 2. Überladen zur Vereinfachung des Methodenaufrufs, obwohl
> Kenntnis der übergebenen Werte von Bedeutung ist. Die in der
> Überladung mit weniger Parametern an die parameterreichere
> Methodenversion übergebenen Werte sind dokumentiert und
> damit Teil der Schnittstelle.
In einer Dokumentation auf eine parameterreichere Methodenversion, inkl.
den übergebenen Werten zu verweisen stellt für mich sowieso bereits
einen Fehler dar. Nicht nur, dass ich damit, wenn auch eventuell
ungewollt, Kopplungen hergestellt habe, sondern auch einen grundlegenden
Fehler bei der Dokumentation beging, nämlich das "Wie" zu beschreiben
anstatt dem "Was".
Um unser Paradeexemplar File.Open(string, FileMode)[1] heranzuziehen:
"Öffnet einen FileStream für den angegebenen Pfad mit Lese- und
Schreibzugriff."
> Hier muss ich widersprechen. Optionale Parameter würden meiner Ansicht
> nach aufgrund ihrer Vorteile (bessere Benutzbarkeit, explizitere
> Schnittstelle, Zusicherung nicht nur in der Dokumentation) durchaus
> den Aufwand für eine zusätzliche Überprüfung durch den Compiler/CLR
> rechtfertigen.
Man muss hier ganz klar unterscheiden zwischen 'besser' und 'einfacher',
denn Methoden mit optionalen Attributen lassen sich vielleicht einfacher
erstellen, verlieren aber Flexibilität und geringe Kopplung.
Explizitere Schnittstellen (bzw. auch Zusicherung nicht nur in der
Dokumentation, was sich ja aus expliziteren Schnittstellen ergibt) kann
man auch anders erreichen, z.B: durch ein Attribut, auch wenn ich nach
wie vor der Meinung bin, dass diese "explizitere Schnittstelle" gegen
das Prinzip von Information Hiding verstößt.
> Die brauche ich nicht, da im Normalfall Änderungen an den
> Standardwerten optionaler Parameter ebenso häufig auftreten wie das
> Ändern von Methodensignaturen etc., was eine Veränderung der
> Schnittstelle zur Folge hätte.
Ich gebe ja zu, dass derartige Fehlerquellen in der Praxis irrelevant
sind, aber trotzdem gibt es sie. Nur weil ein Fehler selten auftritt
heißt das nicht, dass er gar nicht auftritt.
grüße
Bernhard Huemer
[1]: http://msdn2.microsoft.com/de-de/library/system.io.file.open.aspx
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > Theoretisch besteht aber die Möglichkeit. Eine Konstante ist eben
> > semantisch nicht äquivalent zu einer 'ReadOnly'-Variablen oder
> > -Eigenschaft. Konstanten haben, ebenso wie Standardparameter, etwas
> > endgültiges.
>
> Irgendwie klingt das für mich als würdest du sagen, dass man den Fehler
> ohnehin bereits mit Konstanten machen kann, warum also nicht auch noch
> mit optionalen Parametern. Auch wenn du das nicht so meinst, aber es
> läuft darauf hinaus.
Ja, ich meine das so, insbesondere an Thomas gerichtet, der ja C# so gut
findet, weil es angeblich "lean and clean" ohne jegliche Magie auskommt.
Mein Hinweis auf die Konstanten sollte lediglich diese Fehlwahrnehmung
aufdecken. Dennoch halte /ich/ sowohl öffentliche Konstanten als auch
optionale Parameter für sehr wichtig, da sie richtig eingesetzt Vorteile mit
sich bringen. Wie gesagt, Überladungen sind nicht gleichbedeutend mit
optionalen Parametern und öffentliche nur lesbare Variablen/Eigenschaften
nicht gleichbedeutend mit öffentlichen Konstanten. Beides hat seine
Berechtigung und seine begründeten Einsatzzwecke.
> > Hier hat Paul das Beispiel der Dateizugriffsmethoden gebracht, wo bei
> > Überladungen unzulässigerweise Informationen versteckt werden, obwohl
> > diese für die Verwendung der Methode von Bedeutung sind.
>
> Pauls Beispiel wurde meiner Meinung nach widerlegt durch die Tatsache,
> dass File.Open(string, FileMode) mit optionalen Parametern nicht
> realisierbar wäre, da ein Standard Parameter variabel ist.
Welcher Parameter ist variabel? Reflector zeigt für .NET 2.0:
\\\
Public Shared Function Open( _
ByVal path As String, _
ByVal mode As FileMode _
) As FileStream
Return _
File.Open( _
path, _
mode, _
IIf(mode = FileMode.Append, FileAccess.Write,
FileAccess.ReadWrite), _
FileShare.None _
)
End Function
Public Shared Function Open( _
ByVal path As String, _
ByVal mode As FileMode, _
ByVal access As FileAccess _
) As FileStream
Return File.Open(path, mode, access, FileShare.None)
End Function
Public Shared Function Open( _
ByVal path As String, _
ByVal mode As FileMode, _
ByVal access As FileAccess, _
ByVal share As FileShare _
) As FileStream
Return New FileStream(path, mode, access, share)
End Function
///
Die drei Überladungen liessen sich durch folgende zwei Methoden ersetzen:
\\\
Public Shared Function Open( _
ByVal path As String, _
ByVal mode As FileMode, _
ByVal access As FileAccess, _
Optional ByVal share As FileShare = FileShare.None _
)
Return New FileStream(path, mode, access, share)
End Function
Public Shared Function Open( _
ByVal path As String, _
ByVal mode As FileMode, _
Optional ByVal share As FileShare = FileShare.None _
)
Return _
New FileStream( _
path, _
mode, _
IIf(mode = FileMode.Append, FileAccess.Write,
FileAccess.ReadWrite), _
share _
)
End Function
///
> Selbst wenn der Standard Parameter anfangs konstant ist, verbaut man
> sich mit optionalen Parametern nur die Möglichkeit diesen Standard
> Parameter im Laufe von Änderungen variabel zu ermitteln.
>
> Um es also nochmal klarzustellen: Der geringere Schreibaufwand
> rechtfertigt nicht den Verlust an Flexibilität und geringerer Kopplung.
Beim 'FileSteam'-Konstruktor ist die Kopplung nicht geringer. Zusicherungen
stehen nur nicht im Code, sondern in der Dokumentation. Das ist schlechter,
als wenn sie direkt im Code bzw. der Methodensignatur stehen würden.
> > Bewege den Mauszeiger über den 'Print()'-Aufruf. Im Hinweistext
> > erscheint "Public Shared Sub Print([Message As String = "foo"])".
>
> Wie bereits erwähnt, dreht es sich aber um Printmedien. Da könnt ich
> ja genauso mit der Dokumentation argumentieren, die im Hinweisetext
> erscheint.
Mir ist nicht klar, worauf du hinaus willst. Üblicherweise liest man Code
selten in gedruckter Form.
> > Paul Werkowitz ist meine NNTP Identität. Ein Pseudonym sozusagen.
> damit ist deine Glaubwürdigkeit restlos dahin.
Ich kenne Pauls Identität, das ist schon ok.
Es sind Gründe vorhanden, die ich respektiere,
damit werte ich nicht irgendwelche Aussagen.
ciao Frank
--
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET
sprichst du von dieser MsgBox?
http://msdn2.microsoft.com/en-us/library/139z2azd.aspx
wenn man halt alles (4 verschiedene Gruppen) einfach in einen einzigen Enum hineinpresst,
dann wird das durchaus evtl. etwas kürzer, glänzt aber wohl kaum als Vorbild...
Und '21' sind es doch nur, weil MessageBox.Show _zusätzliche_ Optionen bietet.
Diesen Vergleich kauft dir niemanden ab.
> insbesondere an Thomas gerichtet, der ja C# so gut findet,
Die Mehrzahl hier finden C# gut.
Von meiner Seite aus nicht nur gut, sondern *extrem* gut!
VB.NET 2.0 hat sicherlich von dem Nachteil, allen möglichen
"Kram" noch mitschleppen zu müssen schon ein
bisschen ablegen können, aber richtig wie C#
wirds nicht werden. Gut, C# hat den Vorteil durch
Neuspezifikation wesentlich besser auf die
.NET Eigenheiten eingehen zu können.
VB.NET versucht sich momentan durch Entwicklung
eigener kleiner Verbesserungen ein bisschen vom
abzuheben, aber das reicht lange nicht.
> Nein, nicht gleichsetzen! Überladene Methoden sind etwas aganz anderes
> als Defaultparameter! Eine bestimmte Klasse von Problemen kann durch
> beide gelöst werden, trotzdem unterscheiden sich die Features!
War vielleicht ungünstig formuliert, ich wollte damit lediglich
ausdrücken, dass ich davon ausgehe, dass die beiden Varianten in der
Verwendung von einem aufrufenden Benutzer nicht unterscheiden dürfen um
einen objektiven Vergleich ziehen zu können.
> Aber bedenke: Du hast heute z.B. die Situation
>
>
> File.Open(string fn, FileMode fm, FileAccess fa )
> {
> Open( fn, fm, FileAccess.ReadWrite);
> }
>
> und in deinem Code schreibst du andauernd
>
> File.Open( "temp.txt", FileMode.Open )
>
> weil du eben weißt, dass der Default-Param für Access ReadWrite ist.
Mit dieser Annahme liegt eben ein entscheidender Irrtum vor, der sich
bereits von Beginn an durchzieht, da ich die Wahl der Methode nicht
anhand der Überladungen treffe, sondern aufgrund der entsprechenden
Dokumentation.
Zwar wurde diese bereits öfter von mir erwähnt:
"Öffnet einen FileStream für den angegebenen Pfad mit Lese- und
Schreibzugriff."
Mehr muss ich nicht wissen, sollte sich diese Verhalten ändern, liegt
ganz klar ein Breaking Change vor, da die Dokumentation verletzt wurde
und hat in erster Linie nichts mit Überladungen zu tun, da ein
derartiger Breaking Change auch bei Methoden mit optionalen Parametern
nicht ausgeschlossen werden kann.
> Eine Vereinfachung des Programmiermodells rechtfertigt idR erhöhte
> Komplexität in den Tools.
Sollte man allerdings ein Stadium der Abhängigkeit der entsprechenden
Tools erreicht haben, ist man definitiv zu weit gegangen und genau das
würde bei optionalen Parametern bzg. dem Build Management der Fall sein.
> Korrekt. Insofern sind die beiden Beispiele nicht ganz identisch. ICh
> wollte damit nur klarmachen, dass eben recompiliert werden muss, wenn
> man die Vorgabewerte ändert. Dies ist meist das gewünschte Verhalten.
Natürlich muss neu kompiliert werden, das Problem ist aber, dass es
möglicherweise gar nicht, bzw. nur recht subtil auffällt. Bei sonstigen
Änderungen der öffentlichen Schnittstelle führt allerdings kein Weg
daran vorbei.
grüße
Bernhard Huemer
Die unerwünschten Ergebnisse gibt's halt bei Änderung im Aufruf innerhalb
einer Überladung in allen abhängigen Komponenten. Ob das besser ist? Das
Problem ist jedenfalls die Änderung in der Schnittstelle, die es zu
vermeiden gilt. Beim 'FileStream'-Konstruktor ist 'FileShare.Read' zwar
nicht in allen Überladungen sichtbar, aber dennoch Teil der Schnittstelle
(angeführt in der Dokumentation).
"Frank Dzaebel" <Po...@FranksSeite.de> schrieb:
>> insbesondere an Thomas gerichtet, der ja C# so gut findet,
>
> Die Mehrzahl hier finden C# gut.
> Von meiner Seite aus nicht nur gut, sondern *extrem* gut!
>
> VB.NET 2.0 hat sicherlich von dem Nachteil
VB.NET vs. C# steht hier nicht zur Debatte. Dass wir hier unterschiedlicher
Meinung sind, sollt mittlerweile jeder, der regelmässig mitliest, wissen.
> IMHO:
> Eine API/Schnittstelle als 'Kontrakt' soll zwischen mir (vollständig sichtbar
> in meinem Source)
> und der Zielmethode streng definiert sein,
> aber nicht noch über eine versteckte Zusatzklausel im Compiler/generiertem
> Code.
Kann ich nur zustimmen.
"Kontrakt" ist ein wichtiges Argument.
Ist eigentlich schon das Argument gefallen, dass so
(in C#) der Compiler wesentlich performanteren Code
generieren kann?
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > 2. Überladen zur Vereinfachung des Methodenaufrufs, obwohl
> > Kenntnis der übergebenen Werte von Bedeutung ist. Die in der
> > Überladung mit weniger Parametern an die parameterreichere
> > Methodenversion übergebenen Werte sind dokumentiert und
> > damit Teil der Schnittstelle.
>
> In einer Dokumentation auf eine parameterreichere Methodenversion, inkl.
> den übergebenen Werten zu verweisen stellt für mich sowieso bereits
> einen Fehler dar.
Das Problem ist, dass dieses Wissen z.B. bei den 'FileStream'-Konstruktoren
zur Auswahl des passenden Konstruktors erforderlich ist. Daher muss es auch
Teil der Schnittstelle sein. Ich bin der Ansicht, dass es besser ist, das
Wissen direkt als Teil des Vertrags in der Signatur zu spezifizieren,
anstatt es in "Remarks"-Abschnitten der Dokumentation dahingammeln zu
lassen.
> Nicht nur, dass ich damit, wenn auch eventuell ungewollt, Kopplungen
> hergestellt habe, sondern auch einen grundlegenden Fehler bei der
> Dokumentation beging, nämlich das "Wie" zu beschreiben
> anstatt dem "Was".
Letztendlich ist es ein "Was" und kein "Wie", wenn in der Dokumentation
steht, was die Methode macht (Öffnen unter Verwendung von 'FileShare.Read'
bei Überladungen ohne 'FileShare'-Parameter). Hier werden eindeutig
optionale Parameter mit Überladungen unzureichend simuliert.
> > Hier muss ich widersprechen. Optionale Parameter würden meiner Ansicht
> > nach aufgrund ihrer Vorteile (bessere Benutzbarkeit, explizitere
> > Schnittstelle, Zusicherung nicht nur in der Dokumentation) durchaus
> > den Aufwand für eine zusätzliche Überprüfung durch den Compiler/CLR
> > rechtfertigen.
>
> Man muss hier ganz klar unterscheiden zwischen 'besser' und 'einfacher',
> denn Methoden mit optionalen Attributen lassen sich vielleicht einfacher
> erstellen, verlieren aber Flexibilität und geringe Kopplung.
Deshalb sind optionale Parameter genausowenig Allheilmittel wie
Überladungen. Keine der beiden Möglichkeiten ist universal optimal, sondern
man muss von Fall zu Fall die bessere Lösung wählen und kann ggf. auch
mischen.
> Explizitere Schnittstellen (bzw. auch Zusicherung nicht nur in der
> Dokumentation, was sich ja aus expliziteren Schnittstellen ergibt) kann
> man auch anders erreichen, z.B: durch ein Attribut, auch wenn ich nach
> wie vor der Meinung bin, dass diese "explizitere Schnittstelle" gegen
> das Prinzip von Information Hiding verstößt.
Schnittstellen müssen immer so explizit sein, wie dies notwendig ist. Wenn
es beim Öffnen einer Datei notwendig ist, zu wissen, mit welchem
'FileShare'-Wert sie geöffnet wird, und das ist m.E. notwendig, dann sollte
diese Information auch Teil der Schnittstelle sein.
"Thomas Scheidegger [MVP]" <spam.ne...@swissonline.ch> schrieb:
>> So ist 'MsgBox' aus VB.NET dem 'MessageBox.Show' mit seinen 21
>> Überladungen
>> in Sachen Benutzbarkeit überlegen.
>
> sprichst du von dieser MsgBox?
> http://msdn2.microsoft.com/en-us/library/139z2azd.aspx
>
> wenn man halt alles (4 verschiedene Gruppen) einfach in einen einzigen
> Enum hineinpresst,
> dann wird das durchaus evtl. etwas kürzer, glänzt aber wohl kaum als
> Vorbild...
Ich sage nicht, dass 'MsgBox' optimal ist. Sicherlich wäre es sinnvoller
gewesen, die Aufzählungstypen thematisch zu trennen und zusätzliche
optionale Parameter einzuführen.
> Und '21' sind es doch nur, weil MessageBox.Show _zusätzliche_ Optionen
> bietet.
Selbst bei Implementierung mit zusätzlichen optionalen Parametern + ggf. 2
bis 3 Überladungen wäre 'MsgBox' wesentlich einfacher zu nutzen als es mit
den momentanen 21 Überladungen ist.
"Frank Dzaebel" <Po...@FranksSeite.de> schrieb:
>> Eine API/Schnittstelle als 'Kontrakt' soll zwischen mir (vollständig
>> sichtbar in meinem Source)
>> und der Zielmethode streng definiert sein,
>> aber nicht noch über eine versteckte Zusatzklausel im
>> Compiler/generiertem Code.
>
> Kann ich nur zustimmen.
> "Kontrakt" ist ein wichtiges Argument.
Ich sage in der Diskussion seit geraumer Zeit "Vertrag" dazu.
> Ist eigentlich schon das Argument gefallen, dass so
> (in C#) der Compiler wesentlich performanteren Code
> generieren kann?
Kannst du dies näher ausführen? Gerade in Zeiten von JIT-Optimierung dürfte
sich dieses Argument wohl relativieren.
> Welcher Parameter ist variabel? Reflector zeigt für .NET 2.0:
Falls es anscheinend nicht derartig auffallen sollte, wie ich meinte,
dann erklär ich dir halt gern, dass der 3. Parameter (FileAccess) vom
2. Parameter (FileMode) abhängt und demzufolge alles andere als
konstant ist ..
> Die drei Überladungen liessen sich durch folgende zwei Methoden ersetzen:
Wobei dein Beispiel nichts zu bedeuten hat, denn es geht ganz klar am
derzeitigen Ausgangsstand vorbei, da es entsprechend angepasst wurde
um einen Vorteil zu erzielen. Es gibt keine Methode File.Open(string,
FileMode, FileShare).
Mal ganz abgesehen davon sollte doch die Verwendung von optionalen
Parametern den Aufwand derartig minimieren, so dass eigentlich nur
mehr eine Methode entwickelt werden müsste. Hier geht der Vorteil
bezüglich einfacherer Benutzung nur sehr beschränkt auf.
> Mir ist nicht klar, worauf du hinaus willst. Üblicherweise liest man
> Code selten in gedruckter Form.
Diese Annahme wurde allerdings zu Beginn dieser Teildiskussion getroffen:
> Und noch etwas: Die hier so oft zitierte Intellisense-Unterstützung
> mit allen tollen Überladungen habe ich nicht, wenn ich Ausdrucke oder
> Code in Büchern lese. Welche der Überladungen mit 4 Parametern gerade
> verwendet wird ist dann schon recht schwer zu erkennen...
grüße
Bernhard Huemer
gewisse Anonymität für unverbindliche Anfragen hier meinetwegen,
aber nicht wenn er dann Sprüche macht wie:
http://groups.google.de/group/microsoft.public.de.german.entwickler.dotnet.csharp/msg/eb4213e23e366586
"Vielleicht möchtest du dich ebenfalls outen?"
und Behauptungen von 'Erfahrung & vielen Büchern' aufstellt, die mit einem Pseudonym niemand jemals nachvollziehen kann.
Da hast du in der Tat Recht. Dies würde ich befürworten, und mache es
auch so. Auch wenn sich dir die Haare aufstellen und meine credibility
auf 0 sinjen mag: ich mache das sogar auch mit einigen r/w Daten so.
Aber dies ist eine andere Geschichte, sie vielleicht später in einem
anderen Thread erzählt werden soll.
>
> Beides zieht den selben Effekt nach sich: Man verbaut sich Flexibilität,
> die man unter Umständen im Nachhinein braucht.
>
In deinem Beispiel bringt es nichts, eine Indirektionsstufe (hier:
property) zwischenzuziehen.
Dem client ist es doch völlig wurscht, ob er an ein property bindet,
oder an ein Feld: Die Syntax ist (gottseidank!) die Gleiche. Im Ggensatz
zu z.B. C++ habe ich bei C# die Möglichkeit, mit Feldern anzufangen -
und später (aber wirklich erst dann, wenn ich's wirklich brauche!!!) das
durch ein property zu ersetzen. Dies ist für mich ein Beispiel eines
optimal durchdachten Sprachmittels.
Auch mit Vorgabewerten würdest du keine Flexibilität einbüßen. Wie ich
bereits dargestellt habe, hast du vergleichbare Möglichkeiten wie bei
overloading. Vorgabeparameter haben aber einige Vorteile mehr, die
overloading nicht bieten kann (wenn es um das Konzept eines vorgegebenen
Wertes als optionalen Parameter geht).
> > Selbstverständlich gibt es Situationen, wo das nicht passt. Dann muss
> > man eben andere Sprachmittel nehmen, z.B. Überladung. Was man jedoch
> > nicht machen sollte, und was hier in der NG eben häufig püassiert, ist
> > folgender Schluss: es gibt Situationen, für die sind Default-Parameter
> > nicht geeignet. Ergo: Dfault-Parameter sind schlecht. (und da C++ sie
> > hat, erst recht).
>
> Das Problem ist aber, dass sich die Situation im nachhinein ändern und
> man bei optionalen Parametern aufgrund mangelnder Flexibilität nicht
> mehr entsprechend darauf reagieren kann.
>
Ich denke schon, wie ich bereits mehrfach dargelegt habe. Gibt es hier
ein Mißverständbnis? Könntest du mir nochmal eine Situation geben, wo
die Flexibilität verloren ginge?
Grüße - Paule
oder eben bei zugelieferten Bibliotheken mit notorisch schlechter Doku
durch den Sourcecode zu gehen, um weitere Überladungen mit evt.
interssanten weiteren Params zu finden.
> Schnittstellen müssen immer so explizit sein, wie dies notwendig ist.
> Wenn es beim Öffnen einer Datei notwendig ist, zu wissen, mit welchem
> 'FileShare'-Wert sie geöffnet wird, und das ist m.E. notwendig, dann
> sollte diese Information auch Teil der Schnittstelle sein.
>
Full ack. Besser hätte ich es nicht sagen können....
Paule
> Die unerwünschten Ergebnisse gibt's halt bei Änderung im Aufruf
> innerhalb einer Überladung in allen abhängigen Komponenten. Ob das
> besser ist?
Der einzig mögliche Fehler der bei Änderungen in einer Überladung
auftreten kann, ist klarerweise ein Breaking Change bezüglich der
Dokumentation. Aber das sind Fehler, die nicht nur im Speziellen
bei Überladungen auftreten, davor sind Methoden mit optionalen
Parameter ebenfalls unter Umständen betroffen.
Ich weiß zwar auf was du hinaus willst, nämlich dass bei optionalen
Parametern nach wie vor der selbe Parameter wie immer verwendet wird,
aber Methoden mit optionalen Parametern sind ja genauso wenig per
Definition vor Breaking Changes geschützt. Warum also diesbezüglich
differenzieren?
Sollte es allerdings kein Breaking Change sein, ist es ja auch gewollt,
dass das "neue" Verhalten übernommen wird. Es muss ja nicht zwangsweise
wirklich "neu" sein zumindestens für Außenstehende, ganz nach dem Motto:
"Viele Wege führen nach Rom." Mit optionalen Parametern legt man sich
aber auf einen Weg fest, der nicht mehr gewechselt werden darf.
> Das Problem ist jedenfalls die Änderung in der Schnittstelle, die es
> zu vermeiden gilt.
An dieser Aussage erkennt man, dass wir auch ein wenig aneinander vorbei
reden. Ich sehe das Problem nämlich bereits viel grundlegender, nämlich
interne Implementierungsdetails in die öffentliche Schnittstelle mit
aufzunehmen.
Um meinen Standpunkt nochmal klar zu erläutern:
Weniger Schreibarbeit ist für mich lange kein vernünftiges Argument für
bestimmte Features in einer Sprache, wenn dabei Grundprinzipien des
entsprechenden Paradigmas verletzt werden. In diesem Fall geht es eben
um Information Hiding und intern verwendete aber trotzdem
veröffentlichte Parameter, die genau das verletzen.
grüße
Bernhard Huemer
Schön für dich. Die BCL ist hier wirklich gut, und MSDN ist so ziemlich
das Beste, was ich kenne. aber ich könnte dir einige Biblitheken senden,
die hier zugeliefert werden, da kannst du die Doku in die Tonne treten -
wenns denn überhaupt was zu treten gibt, weil oft Fehlanzeige. (Ich
meine hier nicht die automatisch generierten Tags, sondern
*Dokumentation* also zusätzliche Information, die aus dem Programmtext
nicht direkt hervorgeht).
> Mehr muss ich nicht wissen, sollte sich diese Verhalten ändern, liegt
> ganz klar ein Breaking Change vor, da die Dokumentation verletzt wurde
> und hat in erster Linie nichts mit Überladungen zu tun, da ein
> derartiger Breaking Change auch bei Methoden mit optionalen Parametern
> nicht ausgeschlossen werden kann.
Stimmt schon, aber ist in der Praxis oft nicht so. Wir haben es mit
realen Programmierern zu tun, die unter Zeitdruck ein nicht
fehlerfreies, lediglich die Tests bestehendes Ergebnis abliefern. Ich
muss in einer solchen Welt mein Produkt fertig machen.
Grüße - Paule
Korrekt. Hier kommt es darauf an, dass der Wert variabel ist. Genau dann
handelt es sich aber nicht um einen "Default-Parameter", denn es gibt
offensichtlich keinen vernünftigen Default-Wert.
Für diese Aufgabenstellung sind Vorgabewerte in der Tat ungeeignet.
>
> Ein ~ähnlicher~ Fall beim [kurzzeitigen] 'übersteuern' von anderweitig vorbestimmten Parametern
> Int32.ToString( String ) // = NumberFormatInfo.CurrentInfo
> Int32.ToString( String, IFormatProvider )
> hier passen Default-Arguments schon gar nicht hin.
>
auch richtig, da gleiche Situation.
> Neben diesen paar Interpretationen von Überladungen
> sehe ich eben kaum Nutzen für zusätzlich auch noch Default-Arguments (brächte eher Verwirrung).
>
Doch, nämlich genau dort, wo ein wirklicher Default-Wert besteht. Das
Beispiel
Währung( int value, Currency c = Currency.Euro )
ist vielleicht nicht optimal, zeigt aber was ich meine.
Natürlich könnte man die Information "Euro" variabel halten und wäre
somit in der amerikanischen Version der Library in der Lage, dies
automatisch durch Dollar zu ersetzen. Nur: Genau das will ich nicht.
Paule
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > Die unerwünschten Ergebnisse gibt's halt bei Änderung im Aufruf
> > innerhalb einer Überladung in allen abhängigen Komponenten. Ob das
> > besser ist?
>
> Der einzig mögliche Fehler der bei Änderungen in einer Überladung
> auftreten kann, ist klarerweise ein Breaking Change bezüglich der
> Dokumentation. Aber das sind Fehler, die nicht nur im Speziellen
> bei Überladungen auftreten, davor sind Methoden mit optionalen
> Parameter ebenfalls unter Umständen betroffen.
Genau! Dennoch ist es bei optionalen Parametern dem Entwickler
ersichtlicher, dass das Ändern eines Standardwertes auch eine Änderung der
Schnittstelle bedeutet.
> Ich weiß zwar auf was du hinaus willst, nämlich dass bei optionalen
> Parametern nach wie vor der selbe Parameter wie immer verwendet wird,
> aber Methoden mit optionalen Parametern sind ja genauso wenig per
> Definition vor Breaking Changes geschützt. Warum also diesbezüglich
> differenzieren?
Darauf will ich nicht hinaus. Selbstverständlich besteht auch bei optionalen
Parametern die Gefahr einer inkompatiblen Änderung der Schnittstelle.
Allerdings ist man weniger geneigt, diese Änderung durchzuführen, da das
Anführen des Parameterwertes in der Argumentliste der Methode besser zum
Ausdruck bringt, dass es sich um einen optionalen Parameter handelt.
Im Falle von 'FileShare.Read' bei den Überladungen des Konstruktors von
'FileStream' ohne 'FileShare'-Parameter wäre eine Änderung in beiden Fällen
unzulässig, da die Zusicherung, die hinsichtlich des 'FileShare'-Wertes
erforderlich ist und auch gegeben wird, gebrochen würde.
Anders: Entweder ist es wichtig, den Parameterwert zu kennen, dann sind
optionale Parameter die ideale Lösung, oder es ist unwichtig, dann wird man
Überladungen den Vorzug geben.
> Sollte es allerdings kein Breaking Change sein, ist es ja auch gewollt,
> dass das "neue" Verhalten übernommen wird. Es muss ja nicht zwangsweise
> wirklich "neu" sein zumindestens für Außenstehende, ganz nach dem Motto:
> "Viele Wege führen nach Rom." Mit optionalen Parametern legt man sich
> aber auf einen Weg fest, der nicht mehr gewechselt werden darf.
Das Ändern des Wertes, der an eine Überladung intern übergeben wird, ist nur
dann möglich, wenn dieser Wert nicht Teil der Schnittstelle ist, also nicht
spezifiziert ist und seine Kenntnis auch nicht für die Nutzung notwendig
ist. Dies trifft nur auf einen Bruchteil der Fälle zu.
> > Das Problem ist jedenfalls die Änderung in der Schnittstelle, die es
> > zu vermeiden gilt.
>
> An dieser Aussage erkennt man, dass wir auch ein wenig aneinander vorbei
> reden. Ich sehe das Problem nämlich bereits viel grundlegender, nämlich
> interne Implementierungsdetails in die öffentliche Schnittstelle mit
> aufzunehmen.
Hältst du Wissen über den benutzten 'FileShare'-Wert im
'FileStream'-Konstruktor für ein Implementierungsdetail? Ich halte es für
wichtig, um die Methode korrekt nutzen zu können.
> Um meinen Standpunkt nochmal klar zu erläutern:
> Weniger Schreibarbeit ist für mich lange kein vernünftiges Argument für
> bestimmte Features in einer Sprache, wenn dabei Grundprinzipien des
> entsprechenden Paradigmas verletzt werden. In diesem Fall geht es eben
> um Information Hiding und intern verwendete aber trotzdem
> veröffentlichte Parameter, die genau das verletzen.
Schreibarbeit ist für mich auch kein tauglicher Qualitätsindikator für eine
Programmiersprache. Darum geht es aber auch nicht bei optionalen Parametern.
> Ein optionaler Parameter versteckt eben, anders als eine Überladung,
> in welcher der Parameter nicht aufscheint, keine Information.
*Natürlich* wird Information versteckt, es heißt ja nicht umsonst
Information Hiding. Für doch einfach mal deine Gedanken weiter, denn
wenn du dicht nicht auf die Dokumentation beziehen kannst, bleibt dir
nichts anderes übrig als den gesamten Quellcode der Methode in die
Dokumentation zu stellen. Nur so hat man die maximale Information
darüber, was die Methode macht ..
Zusammenfassend würde ich also sagen, geht man den Schritt, den man mit
der Einführung von optionalen Parametern geht, konsequent weiter, bleibt
einem nichts anderes übrig als den gesamten Quellcode als Dokumentation
auszuliefern, denn nur so besitzt der Benutzer eine maximale Menge an
Information und eine absolut "explizite Schnittstelle".
> Wenn die Flexibilität etwas am Verhalten ändert, dann muss ohnehin auf
> sie verzichtet werden.
Genau, aber auch nur *wenn*. Als einfaches Beispiel in bezüglich
Konstante sollten einem doch sofort Stichwörte wie "eagerly loading vs.
lazy loading" einfallen. Das Verhalten bleibt nach außen wirkt absolut
gleich, allerdings wurde es anders implementiert.
> Eine Änderung der Situation bedeutet neue Methoden/Schnittstellen,
> nicht aber das Ändern des Verhaltens bestehender Methoden.
Nein, nicht zwangsweise. Siehe "eagerly loading vs. lazy loading".
Langsam aber sicher driftet die Diskussion ab, wenn ich bereits
"gezwungen" werde zu erklären wie wichtig es ist flexibel zu bleiben ..
grüße
Bernhard Huemer
wenn man etwas als 'wichtig' erkennt, dann gehört dies explizit so in den Aufruf.
Damit erzwingt und dokumentiert man sauber ein stets erwartetes Verhalten direkt im _Source_.
Weggelassene Argumente sagen genauso mit Absicht,
dass es der _Zielmethode_ überlassen sei, geeignete Ergänzungen vorzunehmen.
Der Compiler hat dazwischen nichts heimlich aufzufüllen.
> gewisse Anonymität für unverbindliche Anfragen hier meinetwegen,
> aber nicht wenn er dann Sprüche macht wie:
>
> http://groups.google.de/group/microsoft.public.de.german.entwickler.dotnet.csharp/msg/eb4213e23e366586
> "Vielleicht möchtest du dich ebenfalls outen?"
> und Behauptungen von 'Erfahrung & vielen Büchern' aufstellt, die mit einem
> Pseudonym niemand jemals nachvollziehen kann.
Thomas, er hat Recht. Er ist ein wirklicher Experte im C++ Bereich.
Wir sollten das hier diesbzgl. wirklich respektieren.
(Klar, Du bist sicher auch einer)
Du kannst mir glauben. Ich finde ja einige Ansichten von
Paul gegenüber C# auch nicht besonders "nachvollziehbar",
aber da kann er (sicher) was von uns lernen und das möchte
er sicher auch. Als Buchautor ist man ja immer an allen Feinheiten,
Begründungen, Hintergründen etc. interessiert und muss das
dann meist auch schriftlich (kritisch) begründen.
> > > insbesondere an Thomas gerichtet, der ja C# so gut findet,
> > Die Mehrzahl hier finden C# gut.
> > Von meiner Seite aus nicht nur gut, sondern *extrem* gut!
> > VB.NET 2.0 hat sicherlich von dem Nachteil
> VB.NET vs. C# steht hier nicht zur Debatte.
Dann hätte ich das schlicht etwas anders formuliert.
Aber gut, dann können wir das hier schliessen.
> In deinem Beispiel bringt es nichts, eine Indirektionsstufe (hier:
> property) zwischenzuziehen.
>
> Dem client ist es doch völlig wurscht, ob er an ein property bindet,
> oder an ein Feld: Die Syntax ist (gottseidank!) die Gleiche. Im
> Gegensatz zu z.B. C++ habe ich bei C# die Möglichkeit, mit Feldern
> anzufangen - und später (aber wirklich erst dann, wenn ich's wirklich
> brauche!!!) das durch ein property zu ersetzen. Dies ist für mich ein
> Beispiel eines optimal durchdachten Sprachmittels.
Selbst wenn die Syntax in C# zufälligerweise gleich ist, verhalten sie
sich noch lange nicht gleich. Einerseits wirst du Probleme bekommen,
wenn du diese Felder als ref- oder out-Parameter verwendet hast,
andererseits besitzen Eigenschaften auf IL-Ebene (bzw. auch in anderen
.NET Sprachen) nicht die gleiche Syntax, sind demzufolge also auch
nicht binärkompatibel.
Wenn die Entwickler bei Microsoft ähnlich denken würden, würde es
schlecht um die vielgerühmte Abwärtskompatibilität aussehen. Der Umstieg
von einem Feld auf eine Eigenschaft ist alles andere als
abwärtskompatibel, bzw. stellt einen Breaking Change dar und am
schlimmsten daran ist ja, dass es von Anfang an vermeidbar gewesen wäre.
Alles in allem kann ich sagen, dass es mit einer derartigen Einstellung
völlig unmöglich sein wird meinen Standpunkt zu verstehen, ohne dabei
anmaßend zu wirken.
> Auch mit Vorgabewerten würdest du keine Flexibilität einbüßen. Wie ich
> bereits dargestellt habe, hast du vergleichbare Möglichkeiten wie bei
> overloading.
Kann es zufällig sein, dass du nach wie vor jenes Beispiel damit meinst,
dass vom Compiler mit einer Fehlermeldung quittiert wird?
grüße
Bernhard Huemer
Dann bräuchten wir auch nur selten Überladungen.
> Weggelassene Argumente sagen genauso mit Absicht,
> dass es der _Zielmethode_ überlassen sei, geeignete Ergänzungen
> vorzunehmen.
Du kennst anscheinend die 'FileStream'-Konstruktoren nicht, wo in der
Dokumentation fest definierte "Ergänzungen" dokumentiert sind, eben deshalb,
weil sie wichtig sind.
> Der Compiler hat dazwischen nichts heimlich aufzufüllen.
Tut er auch nicht. Den Wert sieht man ja im Hinweistext beim Überfahren des
Aufrufs mit der Maus und beim Schreiben des Aufrufs in IntelliSense.
"Bernhard Huemer" <bernhar...@gmail.com> schrieb:
> > Ein optionaler Parameter versteckt eben, anders als eine Überladung,
> > in welcher der Parameter nicht aufscheint, keine Information.
>
> *Natürlich* wird Information versteckt, es heißt ja nicht umsonst
> Information Hiding. Für doch einfach mal deine Gedanken weiter, denn
> wenn du dicht nicht auf die Dokumentation beziehen kannst, bleibt dir
> nichts anderes übrig als den gesamten Quellcode der Methode in die
> Dokumentation zu stellen. Nur so hat man die maximale Information
> darüber, was die Methode macht ..
Nein, es gehört eben nur das "Was" und nicht das "Wie" in die Dokumentation.
Ob 'FileShare.Read' oder ein anderer Wert intern benutzt wird, hat jedoch
auch Auswirkungen auf den Aufruf, etwa zeigt es an, ob bestimmte Ausnahmen
auftreten können.
> Zusammenfassend würde ich also sagen, geht man den Schritt, den man mit
> der Einführung von optionalen Parametern geht, konsequent weiter, bleibt
> einem nichts anderes übrig als den gesamten Quellcode als Dokumentation
> auszuliefern, denn nur so besitzt der Benutzer eine maximale Menge an
> Information und eine absolut "explizite Schnittstelle".
Definitiv nein. Ich sage ja, dass man von Fall zu Fall entscheiden muss, ob
es sich um ein unwichtiges Implementierungsdetail handelt (dieses muss nicht
dokumentiert werden und ist einer durchdachten Änderung zugänglich) oder ob
es sich beim Detail um einen Teil des Vertrags handelt (und damit
dokumentiert werden muss und nicht geändert werden darf).
> > Wenn die Flexibilität etwas am Verhalten ändert, dann muss ohnehin auf
> > sie verzichtet werden.
>
> Genau, aber auch nur *wenn*. Als einfaches Beispiel in bezüglich
> Konstante sollten einem doch sofort Stichwörte wie "eagerly loading vs.
> lazy loading" einfallen. Das Verhalten bleibt nach außen wirkt absolut
> gleich, allerdings wurde es anders implementiert.
Das ist ein Beispiel für das "Wie", nicht das "Was", daher muss es auch
nicht dokumentiert werden, /ausser/ es gibt spürbare Seiteneffekte. Alle
spürbaren Seiteneffekte sind Teil des Vertrags und müssen zumindest
dokumentiert werden, besser aber noch in der Schnittstelle explizit
aufscheinen.
> Genau! Dennoch ist es bei optionalen Parametern dem Entwickler
> ersichtlicher, dass das Ändern eines Standardwertes auch eine Änderung
> der Schnittstelle bedeutet.
> Darauf will ich nicht hinaus. Selbstverständlich besteht auch bei
> optionalen Parametern die Gefahr einer inkompatiblen Änderung der
> Schnittstelle. Allerdings ist man weniger geneigt, diese Änderung
> durchzuführen, da das Anführen des Parameterwertes in der
> Argumentliste der Methode besser zum Ausdruck bringt, dass es
> sich um einen optionalen Parameter handelt.
Nein, denn das Ändern des Standardwertes bedeutet einer Überladung
nicht zwangsweise, dass sich das erwartete Verhalten ändert, stellt
somit auch keine Änderung der Schnittstelle dar.
Das Problem ist aber, dass sich der Standardparameter verändern wird.
Um diesbezüglich ein einen Auszug aus Extreme Programming Explained
von Kent Beck anzubringen: "Change is the only constant."
Einzig und allein durch die entsprechende Kapselung kann man
Veränderungen entgegenwirken und genau diese Kapselung ist bei
optionalen Parametern nicht mehr gegeben.
> Anders: Entweder ist es wichtig, den Parameterwert zu kennen, dann
> sind optionale Parameter die ideale Lösung, oder es ist unwichtig,
> dann wird man Überladungen den Vorzug geben.
Dieser Aussage kann ich absolut zustimmen, lediglich sollte es einfach
nie wichtig sein, den Parameterwert zu kennen aus bereits oft genug
genannten Gründen.
> Hältst du Wissen über den benutzten 'FileShare'-Wert im
> 'FileStream'-Konstruktor für ein Implementierungsdetail? Ich halte es
> für wichtig, um die Methode korrekt nutzen zu können.
Absolut sogar, solange die Methode, bzw. der Konstruktor macht, was in
der Dokumentation beschrieben wird. Sollte sich die Dokumentation
diesbezüglich ausschweigen, wird sie mir aber wohl auch kaum erklären
können, was denn diese Standard Parameter, die verwendet werden,
überhaupt bewirken.
> Schreibarbeit ist für mich auch kein tauglicher Qualitätsindikator für
> eine Programmiersprache. Darum geht es aber auch nicht bei optionalen
> Parametern.
Das habe ich auch nicht behauptet sondern lediglich, dass fadenscheinige
Vorteile, wie die einfachere Handhabung für den Entwickler aufgrund z.B:
geringerer Schreibarbeit, nicht in die Sprache aufgenommen werden
dürfen, wenn sie grundlegende Prinzipien des jeweiligen Paradigmas
verletzen.
grüße
Bernhard Huemer
*Das* stimmt allerdings. Hatte ich so nicht direkt bedacht, und kann in
der Tat zu Problemen führen. Liegt aber auch daran, dass hier bei uns
niemand sowas macht wie Felder als ref-Params zu übergeben. Aber hast
natürlich Recht, es *wäre* möglich, und muss daher auf die Negativseite
meiner Argumentation gebucht werden.
Deine weiteren Argumente sind ebenfalls korrekt. "I stand corrected",
wie die Amis immer so schön sagen.
>Alles in allem kann ich sagen, dass es mit einer derartigen Einstellung
> völlig unmöglich sein wird meinen Standpunkt zu verstehen, ohne dabei
> anmaßend zu wirken.
Brilliant formuliert, um zu sagen, dass dein Diskussionspartner keine
Ahnung von den hehren Grundsätzen guten Software-Enguineerings zu haben
scheint. Message ist durchaus angekommen.
Ich nehme für mich in Anspruch, deinen Standpunkt sehr wohl zu
verstehen. Im Gegensatz zu anderen hier hast du tatsächliche Argumente
gebracht, die meinen Horizont erweitert haben. Deswegen wende ich die
Zeit auf, hier zu schreiben.
Ich nehme aber auch für mich in Anspruch, beim Thema Default-Params
anderer Meinung zu sein, und ich denke, ich habe das ausreichend
begründet. Es ist i.O unterschiedlicher Meinung zu sein, man braucht
dabei nicht "anmaßend zu wirken".
>
> > Auch mit Vorgabewerten würdest du keine Flexibilität einbüßen. Wie ich
> > bereits dargestellt habe, hast du vergleichbare Möglichkeiten wie bei
> > overloading.
>
> Kann es zufällig sein, dass du nach wie vor jenes Beispiel damit meinst,
> dass vom Compiler mit einer Fehlermeldung quittiert wird?
>
Selbstverständlich wird das Beispiel mit einer FM quittiert. Denn in C#
gibt es keine Default-Parameter. Das Beispiel dient dazu, zu
demonstrieren, wie es aussehen könnte. Und zwar dann, wenn ich von
Vorgabewerten auf überladene Funktionen umstellen möchte.
Paule
>> "Kontrakt" ist ein wichtiges Argument.
>
> Ich sage in der Diskussion seit geraumer Zeit "Vertrag" dazu.
Ok, bei (ich sage mal "wirklichen") optionalen Parametern
hätte man ja immer einen Matrix-Vertrag/Kontrakt zu unterschreiben.
Also Permutation von n Möglichkeiten müssten unterstützt
werden.
C# hätte da nur die wirklich benutzten.
>> Ist eigentlich schon das Argument gefallen, dass so
>> (in C#) der Compiler wesentlich performanteren Code
>> generieren kann?
>
> Kannst du dies näher ausführen? Gerade in Zeiten von JIT-Optimierung dürfte
> sich dieses Argument wohl relativieren.
Oh, also noch nicht. Und das, wo hier so lange darüber geredet wurde.
Ja, kann ich näher ausführen. Wenn mehr Methoden unterstützt
werden müssen, ist es
(a) ein grösserer Speicheraufwand, da
mehr Signaturen intern verwaltet werden müssen.
(b) Die Ladezeit würde also schon mal hochgehen.
> JIT-Optimierung dürfte sich das Argument wohl relativieren.
Gerade der JITter müsste länger brauchen bei Optionalen
Parametern, denn einen MethodEntry für wenige
Methoden zu erstellen, muss schneller sein als das
für viele zu tun. Der Ablauf/Aufruf der Methode müsste
dann aber (ungeprüft) gleich schnell sein.
Wenn man mal hier nachliest, werden Optionale Parameter als
"Potentially problematic VB.NET features" angesehen.
/Optional parameters\ : "While these can be valuable in some
circumstances, they are also often a significant source of
errors and headaches."
http://en.wikipedia.org/wiki/Comparison_of_C_sharp_and_Visual_Basic_.NET
erstmal tut es mir natürlich leid, wenn die Nachricht derartig schroff
rübergekommen ist, da ich schon Wert auf gewisse Umgangsformen lege.
Allerdings ist es halt offensichtlich, dass wir andere Vorstellungen
von der "optimalen" Sprache haben, denn für mich zählen einfach andere
Werte. Andererseits ist es mir auch nicht möglich mich in deine Lage zu
versetzen, aus ebenfalls bereits genannten Gründen.
> Selbstverständlich wird das Beispiel mit einer FM quittiert. Denn in
> C# gibt es keine Default-Parameter. Das Beispiel dient dazu, zu
> demonstrieren, wie es aussehen könnte. Und zwar dann, wenn ich von
> Vorgabewerten auf überladene Funktionen umstellen möchte.
Aus der Fehlermeldung, die ich angegeben habe, sollte allerdings klar
ersichtlich sein, dass es mit einem VB.NET Compiler übersetzt wurde:
Public Shared Sub f([i As Integer = -1])' and 'Public Shared Sub f()'
cannot overload each other because they differ only by optional
parameters.
grüße
Bernhard Huemer
> Schön für dich. Die BCL ist hier wirklich gut, und MSDN ist so
> ziemlich das Beste, was ich kenne. aber ich könnte dir einige
> Biblitheken senden, die hier zugeliefert werden, da kannst du
> die Doku in die Tonne treten - wenns denn überhaupt was zu treten
> gibt, weil oft Fehlanzeige. (Ich meine hier nicht die automatisch
> generierten Tags, sondern *Dokumentation* also zusätzliche
> Information, die aus dem Programmtext nicht direkt hervorgeht).
Fehlende bzw. unzureichende Dokumentation ist aber ebenfalls kein
Problem, dass sich speziell bei überladenen Methoden auswirkt. Das
Problem besteht bei optionalen Parametern gleichermaßen, da du auch
hier nur mehr mutmaßen kannst, was denn diese Parameter bewirken und
ob der Standard gerade für dich jetzt auch gewünscht ist.
grüße
Bernhard Huemer
Passt schon! War nicht schroff, sondern elegant. Umgangsformen stimmen.
> Allerdings ist es halt offensichtlich, dass wir andere Vorstellungen
> von der "optimalen" Sprache haben, denn für mich zählen einfach andere
> Werte. Andererseits ist es mir auch nicht möglich mich in deine Lage zu
> versetzen, aus ebenfalls bereits genannten Gründen.
Ist ja in Ordnung. Wichtig ist, dass man die Argumente austauscht. Was
dann jeder draus macht ... ich jedenfalls habe wieder was gelernt.
>
> > Selbstverständlich wird das Beispiel mit einer FM quittiert. Denn in
> > C# gibt es keine Default-Parameter. Das Beispiel dient dazu, zu
> > demonstrieren, wie es aussehen könnte. Und zwar dann, wenn ich von
> > Vorgabewerten auf überladene Funktionen umstellen möchte.
>
> Aus der Fehlermeldung, die ich angegeben habe, sollte allerdings klar
> ersichtlich sein, dass es mit einem VB.NET Compiler übersetzt wurde:
>
> Public Shared Sub f([i As Integer = -1])' and 'Public Shared Sub f()'
> cannot overload each other because they differ only by optional
> parameters.
Sorry - war nicht mein Beispiel. VB.NET ist nicht mein Ding.
Hier nochmal mein Beispiel:
A) MIT Vorgabewerten:
void f( int i = -1 ) { ... }
B) OHNE Vorgabewerte (simuliert durch overloading)
void f( int i ) { ... }
void f()
{
f(-1);
}
Du vergibst dir keine Flexibilität, wenn du mit A anfängst und mit B
weitermachst, wenn du wirklich einmal in die Situation kommst, die -1
variabel machen zu müssen.
(was nicht vorkommen sollte, denn dann hätte man von Vornherein keine
Vorgabewerte nehmen sollen).
Nochmal zu dem VB.NET-BEispiel: Die FM des Compilers ist ein wenig
überzogen, denn man könnte durchaus f(3) schreiben, und es gäbe keine
Mehrdeutigkeit. C++ macht dies besser: Da gibt es erst bei einem
mehrdeutigen *Aufruf* eine FM.
Grüße - Paule
> Letztendlich ist es ein "Was" und kein "Wie", wenn in der
> Dokumentation steht, was die Methode macht (Öffnen unter Verwendung
> von 'FileShare.Read' bei Überladungen ohne 'FileShare'-Parameter).
> Hier werden eindeutig optionale Parameter mit Überladungen
> unzureichend simuliert.
Ein "Was" wäre es, wenn man beschreibt, was der Parameter FileShare.Read
bewirkt ohne ihn zu namentlich verwenden, also eben, dass allen
nachfolgenden Zugriffen nach wie vor die Möglichkeit zu Lesen eingeräumt
wird.
> Schnittstellen müssen immer so explizit sein, wie dies notwendig ist.
> Wenn es beim Öffnen einer Datei notwendig ist, zu wissen, mit welchem
> 'FileShare'-Wert sie geöffnet wird, und das ist m.E. notwendig, dann
> sollte diese Information auch Teil der Schnittstelle sein.
Das ist halt deine Ansicht, ich bevorzuge es den Kopf frei zu halten,
indem ich mir derartige Details wegkapseln lasse und einfach der
Dokumentation entnehme, was gemacht wird (siehe oben).
Mir geht es eher so, dass mich anfangs bei zahlreichen zusätzlichen
Parametern "erschlagen" fülle mit Informationen, bzw. Optionen, die
ich mich bei einer simplen Tätigkeit, wie z.B: dem Lesen einer Datei
nicht interessieren müssen. Man steht sozusagen eher vor der "Qual
der Wahl". Trotzdem muss ich bei jedem einzelnen Parameter überprüfen,
ob der Standard für meine Anforderungen bzw. Ziele auch wirklich so
zutrifft.
Allerdings verlassen derartige Argumente den sachlichen Bereich und
gehen ins objektive über, nachdem das meiner Meinung nach reine
Ansichtssache ist.
grüße
Bernhard Huemer
> Du vergibst dir keine Flexibilität, wenn du mit A anfängst und mit B
> weitermachst, wenn du wirklich einmal in die Situation kommst, die -1
> variabel machen zu müssen.
Wenn ich mit A anfange und mit B weitermache, nützt mir das in der Tat
relativ wenig, weil das -1 bereits mal als Standard bekannt war und
wird demzufolge auch in älteren Versionen (falls man Wert auf
Abwärtskompatibilität legt) verwendet, wodurch die Version B völlig
nutzlos wird aufgrund "mangelnder" Verwendung.
Wenn von Anfang an Überladungen benutzt werden, hat man einfach mehr
Flexibilität, was folgendes Beispiel zeigen soll.
--
// Liefert den Namen des Benutzers mit der angegebenen ID.
// Standardmäßig wird der derzeit eingeloggte Benutzer dazu
// verwendet (Annahme: kein wirkliches Multi-User OS).
public string GetUsername(int id = CurrentUser.Id) {
// ...
}
--
Mit der Zeit stellt allerdings das darunterliegende Betriebssystem die
Benutzeridentifzierung um und verlangt komplexere Identifzierungsdaten.
--
// 1. Problem:
// Man kann GetUsername nicht überladen, da nicht unterscheidbar
// wäre welche Version mit GetUsername() nun aufgerufen wird.
[Obsolete()]
public string GetUsername(int id = CurrentUser.Id) {
// ...
}
public string GetUsernameByIdenditity(UserIdentity identity =
CurrentUser.Identity) {
// ...
}
--
Als Vergleich wird die Lösung mit Überladung ebenfalls betrachtet.
--
// 2. Problem:
// Die Standard Version hätte man ja dementsprechend anpassen können,
// so dass diese nicht als obsolet markiert werden muss.
public string GetUsername() {
// return GetUsername(CurrentUser.ID)
return GetUsername(CurrentUser.Identity);
}
[Obsolete()]
public string GetUsername(int id) {
// ...
}
public string GetUsername(UserIdentity identity) {
// ...
}
--
Es sollte also klar ersichtlich sein, dass man mit der Überladung
wesentlich eleganter auf die Veränderung reagieren konnte ohne dabei
nach außen hin das Verhalten zu ändern.
grüße
Bernhard Huemer