Suche: ASP

XML Documentation Comments in C# 👍 👎

Zwar nutzt sicherlich jeder sehr gerne die von Visual Studio eingeblendeten Kommentare während der Entwicklung mit dem .NET-Framework, bei vielen Projekten herrscht hier jedoch häufig akuter Mangel. Dabei wird einem dies für Standardkommentare besonders einfach gemacht.

Ihr müsst dazu lediglich über eine Klasse oder beliebigen Member davon (z. B. Eigenschaft, Methode) drei Schrägstriche ("///") in Folge schreiben, worauf Visual Studio automatisch einen passenden XML-Kommentarblock erstellt, den ihr vervollständigen könnt. Am besten sehen wir uns ein "fertiges" Beispiel an:
Klasse "Person" mit XML-Dokumentationskommentaren
01020304050607080910111213141516171819202122232425262728293031
/// <summary>/// Stellt eine Person dar./// </summary>public class Person {    /// <summary>    /// Liefert den Vornamen oder legt diesen fest.    /// </summary>    public string FirstName {        get;        set;    }
/// <summary> /// Liefert den Nachnamen oder legt diesen fest. /// </summary> public string LastName { get; set; }

/// <summary> /// Lässt die Person sprechen. /// </summary> /// <param name="textToSay">Text, der gesprochen werden soll.</param> public void Say(string textToSay) { /* * Implementierung für Beispiel nicht notwendig. */ }}
Alle wesentlichen Bestandteile (insbesondere Rückgabewerte und Parameter) lassen sich separat beschreiben, wobei es zusätzlich immer eine Zusammenfassung gibt. Diese Informationen werden bei Verwendung dieser Klasse nun angezeigt, ganz so wie man es von integrierten Typen kennt.

Als besonders nützlich stellt sich dies selbstverständlich dann heraus, wenn die Klasse (beispielsweise als Bestandteil einer Programmbibliothek) weitergegeben und von anderen Entwicklern verwendet werden soll. Hier gibt es jedoch noch eine kleine Hürde zu bewältigen, denn unsere – mehr oder weniger – mühsam erstellten Kommentare überleben den Kompilierungsvorgang nicht. Ihr könnt Visual Studio jedoch anweisen, eine separate XML-Datei hierfür zu erstellen, welche ihr zusammen mit der DLL weitergeben könnt. Ihr findet die entsprechende Einstellung in der Projektkonfiguration unter Erstellen -> XML-Dokumentationsdatei.

Wie üblich gibt es weitere Informationen zur Verwendung im MSDN, insbesondere eine Tag-Übersicht.

Variadic Methods in C# 👍 👎

Variadische Funktionen sind Funktionen, die eine unbestimmte Anzahl von Argumenten (→ Arität) entgegennehmen können. Das passende Stichwort an dieser Stelle für PHP-Entwickler ist hauptsächlich func_get_args. Selbstverständlich bietet beispielsweise auch Java eine entsprechende Möglichkeit. Wie ihr sicher bereits befürchtet habt, lege ich den Fokus im weiteren Verlauf jedoch auf C#. Smiley: grinning

Als Beispiel soll uns eine Methode dienen, welche uns die Summe einer beliebigen Anzahl an Zahlen liefert. Zu Vergleichszwecken erinnern wir uns zuerst einmal daran, wie dieses Problem "normal" gelöst werden kann. Die Lösung ist selbstverständlich, ein Feld zu übergeben:
Nicht-variadische Funktion zur Problemlösung
01020304050607
  // Methode definierenpublic int GetSum(int[] list) {    return list.Sum();}
// Methode verwendenint sum = GetSum(new int[] { 1, 2, 3 });
Durch eine minimale Anpassung – nämlich indem wir das params-Schlüsselwort vor dem Parameter ergänzen – wird daraus eine variadische Funktion unter Beibehaltung der bisherigen Funktionalität:
Variadische Funktion zur Problemlösung
010203040506070809
  // Methode definierenpublic int GetSum(params int[] list) {    return list.Sum();}
// Methode verwendenint sum = GetSum(1, 2, 3); // – oder, ebenfalls möglich -int sum = GetSum(new int[] { 1, 2, 3 });
Wie leicht zu sehen ist, handelt es sich soweit letztlich um eine syntaktische Variante, welche nicht unbedingt notwendig ist. Bei Methoden, die sehr häufig z. B. zwei oder drei Argumente erwarten, prinzipiell jedoch auch mehr denkbar wären, erscheint mir eine solche Möglichkeit jedoch durchaus vernünftig. Das .NET-Framework setzt u. a. bei den Methoden String.Format(…) und String.Join(…) auf dieses Vorgehen.

Zuletzt gilt es aber noch auf folgende Besonderheiten hinzuweisen:
  • params-Parameter sind generell optional (d. h. GetSum() wäre möglich)
  • params-Parameter können vor sich fest definierte Parameter besitzen, nicht jedoch danach
  • params-Parameter dürfen pro Methode lediglich einmal auftreten

Use Console Output in C# (Appendix) 👍 👎

In meinem Beitrag zur Verwendung der Konsolenausgabe in C# hatte ich aus naheliegenden Gründen eine asynchrone Verarbeitung gewählt. Mich hat nun jedoch die Frage erreicht, wie die komplette Ausgabe auf einmal abzugreifen geht. Auch das ist selbstverständlich kein Problem – man könnte sogar sagen, noch einfacher.

Wir wollen dazu ein Beispiel wählen, welches uns sehr zügig eine vollständige Antwort liefern sollte. Wir rufen dazu die integrierte Hilfe von ipconfig auf. Die grafische Oberfläche besteht nunmehr nur noch aus einer TextBox output und einer Schaltfläche, für die wir die entsprechende Ereignisbehandlung implementieren:
Ereignisbehandlung implementieren
01020304050607080910111213141516
  // Prozessdaten festlegenProcess process = new Process() {    StartInfo = new ProcessStartInfo() {        Arguments = "/?",               // Parameter für Hilfe-Anzeige        CreateNoWindow = true,          // Konsolenanzeige unterbinden        FileName = "ipconfig",          // Programm        RedirectStandardOutput = true,  // Ausgabe umleiten        UseShellExecute = false         // Betriebssystemshell deaktivieren    }};
// Prozess startenprocess.Start();
// Ausgabe verarbeitenoutput.Text = process.StandardOutput.ReadToEnd();
Ihr solltet jedoch in jedem Fall beachten, dass dieses Vorgehen zur Blockierung der Benutzeroberfläche führt, wenn das externe Programm nicht schnell genug liefern kann. Dies ist daher nur begrenzt zu empfehlen.

Use Console Output in C# 👍 👎

Manchmal kann es erforderlich sein, in eigenen Projekten auf bestehende Konsolenanwendungen zurückgreifen zu müssen. Meist benötigt man dann jedoch auch Zugriff auf die Ausgabe des Programms, z. B. um diese in einer grafischen Benutzeroberfläche mit Windows Forms – ggf. aufbereitet – darzustellen.

Dies lässt sich ganz einfach mit C# lösen. Als kleines Beispiel zeigen wir dazu die Ausgabe des tracert-Befehls in einer entsprechenden Anwendung an. Diese besteht dabei lediglich aus einer TextBox "targetHost", einer ListBox "output" und einem Button – mit Visual Studio sicherlich kein Problem soweit. Smiley: winking

Jetzt müssen wir lediglich noch die Ereignisbehandlung für einen Klick auf die Schaltfläche implementieren:
Ereignisbehandlung implementieren
0102030405060708091011121314151617181920212223
  // Prozessdaten festlegenProcess process = new Process() {    StartInfo = new ProcessStartInfo() {        Arguments = targetHost.Text,    // Eingabe aus TextBox        CreateNoWindow = true,          // Konsolenanzeige unterbinden        FileName = "tracert",           // Programm        RedirectStandardOutput = true,  // Ausgabe umleiten        UseShellExecute = false         // Betriebssystemshell deaktivieren    }};
// Ereignisbehandlung registrierenprocess.OutputDataReceived += (s, eventArgs) => { if(eventArgs.Data != null) { this.Invoke(new Action(() => { this.output.Items.Add(eventArgs.Data); })); }};
// Prozess startenprocess.Start();process.BeginOutputReadLine();
Nun werden alle Ausgaben des Konsolenprogramms asynchron als neue Zeile zu output hinzugefügt. Durch dieses Vorgehen blockiert unsere Oberfläche nicht, so dass damit problemlos weitergearbeitet werden kann. In meinem Fall sieht der Inhalt der ListBox für coders-online.net beispielsweise wie folgt aus:
Ausgabe
01020304050607
Routenverfolgung zu coders-online.net [217.160.176.125] über maximal 30 Abschnitte:
1 <1 ms <1 ms <1 ms Router [192.168.2.1] ( … gekürzt … ) 9 17 ms 16 ms 17 ms coders-online.net [217.160.176.125]
Ablaufverfolgung beendet.
Beachtet zuletzt bitte ggf. auch noch einmal meinen Beitrag zur Freigabe von Ressourcen in C#. Um die Beispiele nicht aufzublähen verzichte ich meist darauf (wie auch auf eine umfassende Fehler- und Ausnahmebehandlung).

NULL for Value Types in C# 👍 👎

Oftmals stolpern Entwickler anderer Sprachen darüber, dass Werttypen (z.B. int, double oder bool) in C# null nicht direkt zugewiesen werden kann, was insbesondere bei der Arbeit mit Datenbanken schnell notwendig wird.

Es gibt jedoch mit Hilfe der Nullable-Struktur eine elegante Lösung hierfür. Dazu wird ganz einfach der gewünschte Werttyp als Typparameter von Nullable angegeben:
Werttyp ohne und mit "Nullable"
0102030405060708091011
  // Werttyp ohne "Nullable"bool isValid;
isValid = true; // "true" zuweisenisValid = null; // Fehler: "null" kann nicht zugewiesen werden!
// Werttyp mit "Nullable"Nullable<bool> isValid;

isValid = true; // "true" zuweisenisValid = null; // "null" zuweisen
Außer der Zuweisbarkeit von null fügt Nullable auch noch Funktionalität zu unserem Objekt hinzu, mit der wir prüfen können, ob ein Wert vorhanden (bzw. das Objekt null) ist:
Nullable-Funktionalität
010203040506
if(isValid.HasValue) {  /**   * "isValid.Value" enthält den Wert;   * dieser ist ohne Nullable deklariert.  **/}
Zusätzlich gibt es noch die Methode GetValueOrDefault(…), deren Nutzen selbsterklärend sein dürfte.

Meiner Meinung nach könnte man nun durchaus auf die Idee kommen, dass diese Schreibweise etwas umständlich ist, "nur" um null zuweisen zu dürfen. Das sah Microsoft offensichtlich ähnlich, weswegen es eine äußerst kompakte Alternative gibt, indem man dem entsprechenden Werttyp schlicht ein "?" anhängt:
Werttyp mit "Nullable" (Kurzschreibweise)
01020304
bool? isValid;
isValid = true; // "true" zuweisenisValid = null; // "null" zuweisen
Dies ist identisch zur oben beschriebenen "ausführlichen" Variante und stellt somit lediglich eine syntaktische Bequemlichkeit dar, die ich jedoch sehr gerne verwende und auch anderen empfehle, das so zu halten.

Weitere Informationen zu diesem Thema finden sich selbstverständlich im MSDN.

Project links

Categories / Archive  |  Übersicht RSS feed

Tags

Search