Methodenaufrufe in C♯
Damit das erste Beispielprogramm in dieser Lektion übersetzt und ausgeführt werden kann, muß der Bau »Microsoft.JScript.dll« referenziert werden. Dies ist bei Verwendung des am Anfang dieses Kurses vorgestellten Skripts zum Übersetzen und Ausführen bereits der Fall. Falls jedoch eine andere Entwicklungsumgebung verwendet werden soll, so muß diese noch entsprechend eingestellt werden. Sollte es aber nicht möglich sein, diese Funktion aufzurufen, kann statt dessen als ein ähnliches Beispiel auch das weiter unten vorgestellte Programm mit »global::System.AppDomain.GetCurrentThreadId()« herangezogen werden.
Einführendes Beispiel
Program.cs
class Example
{ public static void Main()
{ global::System.Console.WriteLine
( global::Microsoft.JScript.MathObject.random() ); }}global::System.Console.Out
0.627406620683017
(Eine mögliche Aussprache von “math object random ” ist /ˈmæθ.ˈɑb.dʒɪkt.ˈræn.dm/.)
Bei der Auswertung des Ausdrucks »global::Microsoft.JScript.MathObject.random()« wird das Programm »global::Microsoft.JScript.MathObject.random« gestartet. Dieses legt für den Aufrufausdruck »global::Microsoft.JScript.MathObject.random()« dann einen double-Wert zwischen »0« und »1« als Wert fest.
Genauer gesagt: Der Wert des Aufrufausdrucks »global::Microsoft.JScript.MathObject.random()« ist ein double-Wert, der bei jeder seiner Auswertungen (bei jeder Programmausführung) zwischen 0 (einschließlich) und ‹ 1−2⁻⁵³ › (also 0,99999999999999988897769753748434595763683319091796875) (einschließlich) liegt; man sagt auch, er liege zwischen 0 (einschließlich) und 1 (ausschließlich). Mehrere Auswertungen ergeben mehr oder weniger zufällige Werte, die gleichmäßig über diesen Bereich verteilt sind, die sogenannten Pseudozufallszahlen.
Die Schreibweise von Aufrufen
Wir führen in dieser Lektion eine neue Art von Ausdruck ein, den Methodenaufruf. Ein Methodenaufruf besteht aus einem Namen, dem ein Paar rundern Klammern »(« »)« folgt. Beispielsweise ist »global::Microsoft.JScript.MathObject.random()« ein Methodenaufruf mit dem Namen »global::Microsoft.JScript.MathObject.random()« und einem folgenden Paar runder Klammern »()«.
- Syntax eines Aufrufs »()«
Ausdruck
.--------------. .-. .-.
--->| Aliaseintrag |--->· ( ·-->· ) ·-->
'--------------' '-' '-'Aliaseintrag
.-------------------------.
| .--------. .-. v .------.
---'--->| global |-->( : )---'--->| Name |--->
'--------' '-' '------'Name
.-----------------------.
| .------. .-. v .------------.
---'--->| Name |-->( . )---'--->| Bezeichner |--->
'------' '-' '------------'
Es handelt sich hierbei um mindestens drei lexikalischen Einheiten: die lexikalischen Einheiten des Namens, eine runde Klammer auf »(« und eine runde Klammer zu »)«.
- Neue, erweiterte Syntax (vereinfacht)
Ausdruck
.----------.
---.----------->| Literal |---------------------------.---->
| '----------' |
| .----------. |
'----------->| Name |---------------------------'
| '----------' |
| .-. .----------. |
'--->( - )-->| Ausdruck |---------------------------'
| '-' '----------' |
| .-. .----------. |
'--->( + )-->| Ausdruck |---------------------------'
| '-' '----------' |
| .-. .----------. .-. |
'--->( ( )-->| Ausdruck |-->( ) )-------------------'
| '-' '----------' '-' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( / )-->| Ausdruck |----'
| '----------' '-' '----------' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( + )-->| Ausdruck |----'
| '----------' '-' '----------' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( - )-->| Ausdruck |----'
| '----------' '-' '----------' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( * )-->| Ausdruck |----'
| '----------' '-' '----------' |
| .--------. |
'----------->| Aufruf |-----------------------------'
'--------'
Aliaseintrag
.-------------------------.
| .--------. .-. v .------.
---'--->| global |-->( : )---'--->| Name |--->
'--------' '-' '------'Name
.-----------------------.
| .------. .-. v .------------.
---'--->| Name |-->( . )---'--->| Bezeichner |--->
'------' '-' '------------'Aufruf
.--------------. .-. .-.
--->| Aliaseintrag |--->( ( )--->( ) )--->
'--------------' '-' '-'
Im Falle dieser hier neu vorgestellten Schreibweise nennen wir die runden Klammern auch Aufrufklammern und den damit geschrieben Ausdruck einen Aufrufausdruck.
Vergleich mit dem Zirkumfixoperator »(« »)«
Die hier neu vorgestellte Schreibweise von Aufrufen mit Klammern »(« »)« ist nicht mit dem früher eingeführten Zirkumfixoperator »(« »)« zu verwechseln, dessen Klammern wir auch als „Ausdruckklammern“ bezeichnet hatten.
- Syntax des schon früher behandelten Zirkumfixoperators »(« »)«
Ausdruck
.-. .----------. .-.
--->· ( ·--->| Ausdruck |--->· ) ·-->
'-' '----------' '-'
Die hier neu behandelten Aufrufklammern stehen immer direkt hinter einem Methodennamen, wie beispielsweise in »global::Microsoft.JScript.MathObject.random()« und bilden mit ihm zusammen einen Ausdruck, während die früher behandelten Ausdruckklammern um einen Ausdruck herum geschrieben werden und mit diesem einen neuen Ausdruck, wie beispielsweise »( 65 )«, bilden.
(Wir sagen, daß Klammern leer seien und direkt hinter einen Namen stehen, auch wenn die Klammern noch Leerraum enthalten oder von dem voranstehenden Namen durch Leeraum getrennt sind, da Leerraum hier keine Rolle spielt.)
Methodennamen
Der eben neu eingeführte Aufrufausdruck beginnt mit einem Namen, allerdings sind nur bestimmte Namen erlaubt. Wir zeigen hier zunächst ein Beispiel mit dem Namen »global::Microsoft.JScript.MathObject.random()«.
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( global::Microsoft.JScript.MathObject.random() ); }}global::System.Console.Out
2207
Der Name »global::Microsoft.JScript.MathObject.random« steht für ein Programm, welches zur Laufzeit bei der Auswertung des Aufrufsausdrucks »global::Microsoft.JScript.MathObject.random« gestartet wird.
Solch ein Programm, das von einem anderen Programm aus aufgerufen wird, wird auch als Unterprogramm bezeichnet. Insbesondere in C♯ nennt man solch ein Unterprogramm eine Methode.
Als Name im Aufrufausdruck sind nur Namen erlaubt, die auch eine Methode bezeichnen. Solche Namen bezeichnen wir als Methodennamen.
Die Schreibweise eines Ausdrucks mit einem Methodennamen und einem folgenden Paar runder Klammern nennen wir einen Methodenaufrufausdruck oder – kurz – einen Aufrufausdruck.
Obwohl Methodennamen keine Felder (oder Eigenschaften) ihrer Klasse sind, bringt der Name »global::Microsoft.JScript.MathObject.random« doch zum Ausdruck, daß die Methode »random« als ein Bestandteil der Klasse »global::Microsoft.JScript.MathObject« angesehen wird. Wir nennen Felder, Eigenschaften und Methoden deshalb vereinheitlichend auch Einträge ihrer Klasse.
Die Bedeutung eines Operators ist wie auch die Bedeutung eines Literals bereits durch die Programmiersprache C♯ (C♯LS ) definiert, während die Bedeutung der in dieser Lektion neu vorgestellten Methoden, wie »global::Microsoft.JScript.MathObject.random«, durch die Dokumentation der Dotnet-Standardbibliothek (“.Net Framework Class Library ”) oder einer andere verwendeten Bibliothek (wie hier »Microsoft.JScript«) festgelegt wird. Alle Methoden der Dotnet-Standardbibliothek können in C♯ -Programmen verwendet werden, daneben gibt es auch noch viele zusätzliche Bibliotheken.
Die Bedeutung von Aufrufausdrücken
Die Methode »global::Microsoft.JScript.MathObject.random« legt beim Ablauf des obenstehenden Programms den Wert des Aufrufausdrucks »global::Microsoft.JScript.MathObject.random()« fest. Jener Wert wird dann von unserem Aufrufrahmen ausgegeben.
»global::Microsoft.JScript.MathObject.random()« bedeutet: „Der Wert dieses Ausdrucks soll zum Zeitpunkt der Auswertung dieses Ausdrucks von der Methode »global::Microsoft.JScript.MathObject.random« festgelegt werden.“
Aufrufvorgänge
Bei der Auswertung eines Aufrufausdrucks wird das von dem Methodennamen angegebene Programm (die Methode) gestartet (denn nur dann kann jenes Programm den Wert des Aufrufausdrucks festlegen). Bei der Auswertung des Ausdrucks »global::Microsoft.JScript.MathObject.random()« wird beispielsweise das Programm »global::Microsoft.JScript.MathObject.random« gestartet und ausgeführt. Dabei wird das aufrufende Programm suspendiert (es ruht vorübergehend) und die aufgerufene Methode wird gestartet und läuft. Das aufrufende Programm läuft erst weiter, wenn die aufgerufenen Methode fertig ist, solange hat die aufgerufene Methode die Kontrolle über den Computer.
Man sagt aber meistens dazu nicht „das Programm »global::Microsoft.JScript.MathObject.random« wird gestartet.“, sondern „die Methode »global::Microsoft.JScript.MathObject.random« wird aufgerufen.“. Programme, die auf die hier gezeigte Weise gestartet und ausgeführt werden können, nennt man ja, wie gesagt, Methoden. Den Start eines solchen Programms bezeichnet man auch als Vorgang des Aufrufs der Methode oder Aufrufvorgang.
Aufrufausdrücke und Aufrufvorgänge
Die Auswertung eines Aufrufausdrucks des Quelltextes bewirkt den Aufrufvorgang bei der Programmausführung.
Wenn es dem Zusammenhang entnommen werden kann, ob ein Aufrufausdruck oder ein Aufrufvorgang gemeint ist, oder wenn die Unterscheidung nicht wichtig ist, spricht man einfach nur von einem Aufruf.
Das Wort „Aufruf“ hat also zwei Bedeutungen:
- den Aufrufausdruck im Quelltext des Programms, beispielsweise »global::Microsoft.JScript.MathObject.random()« und
- den Aufrufvorgang während einer Ausführung des Programms.
Wir hatten zuvor bereits Operatoren kennengelernt, auch hinter diesen verbergen sich eigentlich Programme, die bei der Auswertung eines Operatorausdruck gestartet werden.
Methoden
Im Quelltext eines C♯ -Programms erscheinen nicht die Methoden selber, sondern nur Methodennamen.
Dennoch stellt man sich vor, daß es beim Ablauf des Programms Methoden gibt.
Eine Methode kann man dadurch definieren, daß sie einen bestimmten Namen hat und bei einem Aufruf mit jenem Namen einen Wert liefert, der gewissen Anforderungen genügt.
Klienten
Ein Programm, das eine Methode aufruft oder eine Bibliothek benutzt, wird auch als ein Klient dieser Methode beziehungsweise Bibliothek bezeichnet. Das Wort „Klient“ bedeutet hier so viel wie „Benutzer“, aber man möchte das Wort „Benutzer“ nur für Menschen verwenden.
Elementare und komplexe Ausdrücke
Wir bezeichnen einen Ausdruck, der einen Funktionsaufruf oder einen Operator enthält als einen komplexen Ausdruck. Alle anderen Ausdrücke (wie Literale und Namen) nennen wir elementar.
Ein weiteres Beispiel
Das folgende Programm gibt die Kennung aus, unter der es läuft; es handelt sich dabei um eine ganze Zahl.
Dazu wird die Methode »global::System.AppDomain.GetCurrentThreadId« herangezogen.
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( global::System.AppDomain.GetCurrentThreadId() ); }}global::System.Console.Out
2207
Da die Kennung sich auf einen bestimmten Ablauf unseres Programms bezieht, ist es möglich, daß bei jedem Start unseres Programms eine andere Zahl ausgegeben wird. Weil aber andererseits auch nicht garantiert ist, daß es sich dabei stets um eine andere Zahl handelt, kann man diesen Ausdruck nicht verwenden, wenn man bei jedem Programmstart eine möglichst zufällige Zahl erhalten will. Ansonsten ist es an dieser Stelle des Kurses nicht wichtig, die Bedeutung dieser Zahl näher zu erläutern, da sie hier nur als ein Beispiel für eine neue Schreibweise für Ausdrücke dient, die im folgenden noch näher erklärt werden soll.
Übungsfragen
? Lexikalische Einheiten zählen
Wie viele lexikalische Einheiten enthält der Aufrufausdruck »global::System.AppDomain.GetCurrentThreadId()«?