2013-04-02 13 views
6

In C# herkömmlichen es ist in einem ziemlich objektiv zu schreiben, etwa so:C#: Wie funktionieren sequenzielle Funktionsaufrufe? (Effizienz weise)

MyObj obj = new MyObj(); 
MyReturn ret = obj.DoSomething(); 
AnotherReturn rett = ret.DoSomethingElse(); 

Ich konnte genau wie dies die oben schreiben:

AnotherReturn rett = new MyObj().DoSomething().DoSomethingElse(); 

Doch wie funktioniert das Stack-Frame-Arbeit, wenn Sie eine Reihe von Funktionsaufrufen in einer solchen Reihenfolge haben? Das Beispiel ist ziemlich einfach, aber stellen Sie sich vor, wenn ich 50+ Funktionsaufrufe in Ketten gelegt habe (dies kann möglicherweise in der Art von JavaScript (/ w jQuery) passieren).

Meine Annahme war, dass für jeden Funktionsaufruf eine Rücksprungadresse gemacht wird (zum "Punkt"?) Und der Rückgabewert (ein neues Objekt mit anderen Methoden) dann sofort in den nächsten Funktionsaufruf gepumpt wird Absender. Wie funktioniert das w.r.t. zum Gesamtrückgabewert gelangen (in diesem Beispiel wird die Rücksprungadresse den letzten Funktionswert zu rtt zuordnen)? Wenn ich Kettenrufe halten würde, würde ich schließlich überlaufen? Ist es in diesem Fall sinnvoller, den objektiven Weg einzuschlagen (auf Kosten der "unnötigen" Speicherzuweisung?).

+0

Sie könnten, aber ich würde Ihnen nicht danken, wenn es das Debuggen! –

+0

Hah ja, ich frage rein, weil ich meine jQuery ziemlich genossen habe und es ist nicht ungewöhnlich für mich, überhaupt keine Variablen in ziemlich großen Funktionen zuzuweisen. z.B. Funktion doSomething() {return (someReturnCode.somethingElse(). andSoOn); } –

+1

Etwas wie StringBuilder wird jedoch oft auf diese Weise verwendet (da es eine flüssige Oberfläche bietet). Auch Builder-Klassen für unveränderliche Typen verwenden häufig diese Art von flüssiger Schnittstelle. –

Antwort

2

Es ist genau so, als ob Sie jede Methode in einer separaten Zeile aufgerufen hätten, indem Sie jeder Variablen den Rückgabewert zuweisen und dann die nächste Methode aufrufen.

So sind Ihre zwei Proben effektiv gleich.

Haben Sie einen Reflektor? Sie könnten die beiden Methoden ausprobieren und den generierten IL-Code untersuchen, um genau zu sehen, welche Unterschiede es gibt.

+0

Hey, vielen Dank für diese Antwort. Ich habe versucht, Stack-Frame-Guides nachzuschlagen, aber vieles hat sich nicht direkt an dieses Zeug gerichtet (oder war auf einem sehr hohen Level). –

0

Obwohl die 2 Anrufe gleich sind, aber wenn Sie viele "Punkte" haben, dann ist es irgendwo ein Code-Geruch (Demeter-Gesetz).

Siehe unten discussion

+0

Es ist * kein * Code-Geruch, wenn Sie eine Fluent-Schnittstelle verwenden. http://en.wikipedia.org/wiki/Fluent_interface –

+0

Ah, ich habe noch nie von einer fließenden Oberfläche gehört, aber ich finde, dass ich Klassen entwerfe, um sie anzupassen (unbekannt). z.B. MyClass Append (AnItem-Element) {data.Add (Element); gib das zurück; } –