Vor .net, war ein normales Muster für TryXX
Methoden, um einfach das Argument übergeben-durch-Referenz unverändert zu lassen. Dies war ein sehr nützliches Muster, da es diesen Code zu verstehen, die einen Standardwert verwenden wollte, wie etwas tun könnte:
MyNum = 5;
TryParsing(myString, &myNum);
während Code, der nicht einen Standardwert verwenden wollte konnte verwenden:
if (TryParsing(myString, &myNum))
{ .. code that uses myNum .. }
else
{ .. code that doesn't use myNum .. }
In der früheren Verwendung hätte der aufrufende Code sicherstellen müssen, wurde vor dem Aufruf initialisiert, aber würde nicht über die TryParsing
Rückgabewert kümmern müssen. In der letzteren Verwendung müsste sich der aufrufende Code um den Rückgabewert kümmern, aber er müsste myNum
vor dem Aufruf nicht initialisieren. Die TryParsing
Routine selbst müsste sich nicht darum kümmern, welche Verwendung beabsichtigt war.
C# erlaubt ein solches Muster jedoch nicht sehr gut, es sei denn, TryParsing
ist in einer anderen Sprache geschrieben. Entweder TryParsing
muss so geschrieben werden, dass der vorherige Wert myNum
ohne Vorüberprüfung unbedingt überschrieben wird, der Aufrufer muss ihn unbedingt initialisieren, oder es müssen unterschiedliche Methoden für die beiden Szenarien bereitgestellt werden. Wenn die TryParsing
-Methode in einer anderen Sprache geschrieben wäre, könnte sie sich theoretisch wie die alten Methoden verhalten (schreiben Sie das Argument über Erfolg, und lassen Sie es in Ruhe, wenn nicht), während Sie es weiterhin als out
-Parameter bezeichnen. Ich würde dies jedoch nicht empfehlen, da das schrullige Verhalten nicht auf diesen Parameter beschränkt wäre.
Betrachten wir zum Beispiel, dass ein Verfahren dieser Art ein Argument vom Typ verwendet fooStruct
und fooStruct
hatte einen Konstruktor, der aussah:
fooStruct(string st)
{
fooStruct.TryParse(st, out this);
}
Der Compiler würde mit einem solchen Konstruktor vollkommen glücklich sein, da es schreibt "definitiv" this
. Auf der anderen Seite, wenn ein anderer Code tut:
while(someCondition)
{
var s = new fooStruct(someString);
...
}
Man könnte erwarten, dass s
entweder eine initialisierten Struktur halten (wenn someString
gültig ist) oder leer sein (wenn es nicht ist). Nichts über diesen Code würde vorschlagen, dass s
seinen Wert zwischen Wiederholungen der Schleife behalten könnte. Aber genau das würde wahrscheinlich passieren.
Und außerdem, wenn Sie sich um das Ergebnis kümmern genug, dass Sie nicht standardmäßig verwenden möchten, es sei denn, das war explizit der Wert, der XYZ (geparst usw.) war), dann sollten Sie den Rückgabewert der Methode sowieso überprüfen. –
Hatte nicht daran gedacht, dass der Verbraucher einen Grund hat, den zurückgegebenen Wert zu verwenden, wenn Try false zurückgegeben hat. –