Interpolierte Zeichenfolgen mit C#
Im früheren Beitrag String.Format per Objekt-Eigenschaften hatte ich eine kleine Erweiterungsmethode vorgestellt, um eine etwas besser lesbare Variante der
String.Format
-Methodengruppe vorzustellen. Selbstverständlich wird C# aber beständig weiterentwickelt und so gibt es seit C# 6.0 (.NET 4.6) eine entsprechende Möglichkeit, ohne jedoch – wie in meinem kleinen Beispiel – auf die umfangreichen Formatierungsoptionen verzichten zu müssen:
Beispiele für interpolierte Zeichenfolgen
Die wesentliche Syntax-Erweiterung ist dementsprechend "010203040506070809101112131415
// Einfache Verwendung und Methodenaufrufconst string firstName = "Holger";const string lastName = "Stehle";
string formatted = $"{lastName.ToUpper()}, {firstName}"; // "STEHLE, Holger"
// Basis für Zahlenconst int num1 = 42;
formatted = $"dec: {num1}, hex: {num1:X3}"; // "dec: 42, hex: 02A"
// Dezimalstellen für Zahlenconst double num2 = 13.37;
formatted = $"{num2:N3} / {num2:N4}"; // "13,370 / 13,3700" [DE]
$
" zur Einleitung derartiger Zeichenketten. Dateityp mit C# ermitteln
Das ermitteln eines Dateityps nur durch Prüfen von Rohdaten kann aufwendig und fehlerträchtig sein; praktischerweise steht jedoch die native Funktion
FindMimeFromData
zur Verfügung, welche wir nutzen werden:
Wrapper für native Funktionalität bereitstellen
Die Verwendung gestaltet sich nun sehr intuitiv:
Beachtet jedoch bitte, dass auch diese Funktion u. U. nur begrenzt aussagekräftige Ergebnisse liefern kann und wie üblich verzichtet die Implementierung auf umfangreiche Fehlerbehandlung. Darüber hinaus bietet die native Funktion weitere Möglichkeiten, so beispielsweise das Übergeben eines Dateinamens bzw. einer URL. 01020304050607080910111213141516171819202122232425
public static class DataUtility { public static string GetMimeType(byte[] data) { DataUtility.FindMimeFromData(0, null, data, (uint) data.Length, null, 0, out uint address, 0);
// Daten kopieren und Speicher freigeben IntPtr ptr = new IntPtr(address); string mimeType = Marshal.PtrToStringAuto(ptr); Marshal.FreeCoTaskMem(ptr);
return mimeType; }
[DllImport("urlmon")] private static extern uint FindMimeFromData( uint pBC, string pwzUrl, byte[] pBuffer, uint cbSize, string pwzMimeProposed, uint dwMimeFlags, out uint ppwzMimeOut, uint dwReserverd );}
Traceroute per C#
In früheren Beiträgen hatte ich bereits erläutert, wie man per C# auf eine Konsolenausgabe zugreifen und programmatisch einen Ping durchführen kann. Dieser Beitrag soll nun ein einfaches Tracerouting per C# nachbilden. Dazu implementieren wir im Folgenden eine einfache (und wie üblich auf das Wesentliche reduzierte) Klasse, welche die Funktionalität durch sukzessive Erhöhung des TTL-Wertes für schlichte Ping-Pakete umsetzt.
Klasse implementieren
Die Verwendung gestaltet sich nun sehr einfach:
01020304050607080910111213141516171819202122232425
public class Traceroute : IDisposable { private static readonly byte[] buffer = new byte[] { 0x01, 0x03, 0x03, 0x07 }; // Daten zur Übertragung
private readonly Ping ping = new Ping();
public IEnumerable<PingReply> Send(string hostNameOrAddress, int timeout = 3000) { // Paket mit TTL=1 initialisieren PingOptions pingOptions = new PingOptions(1, false);
PingReply pingReply = null;
do { pingReply = this.ping.Send(hostNameOrAddress, timeout, Traceroute.buffer, pingOptions);
// TTL für nächsten Schritt inkrementieren pingOptions.Ttl++;
yield return pingReply; } while(pingReply.Status != IPStatus.Success); }
public void Dispose() => this.ping.Dispose();}
Klasse verwenden (exkl. Namensauflösung)
Um die entsprechenden Hostnamen zu den jeweiligen IP-Adressen zu ermitteln, kann beispielsweise die Methode 0102030405
using(Traceroute traceroute = new Traceroute()) { foreach(PingReply pingReply in traceroute.Send("coders-online.net")) { Console.WriteLine(pingReply.Address); }}
Dns.GetHostEntry(…)
dienen:
Klasse verwenden (inkl. Namensauflösung)
0102030405060708091011
using(Traceroute traceroute = new Traceroute()) { foreach(string hostNameOrAddress in traceroute.Send("coders-online.net").Select(pR => { try { return Dns.GetHostEntry(pR.Address).HostName; } catch { return pR.Address.ToString(); } })) { Console.WriteLine(hostNameOrAddress); }}
Objekte mit C# dynamisch erzeugen
Insbesondere bei der Entwicklung von unterstützenden Tools kann es hilfreich sein, Objekte dynamisch erzeugen zu können, ohne vorher den konkreten Typ zu kennen. Ich habe so etwas beispielsweise einmal im Rahmen einer interaktiven API-Dokumentation genutzt. Das .NET-Framework bietet hierfür die
Als Basis für das Beispiel soll folgende triviale Klasse dienen:
Die in diesem Beitrag vorgestellte Klasse bietet auch eine Variante mit Typparameter an: Diese Funktionalität ist in der Praxis zur "normalen" Entwicklung jedoch nur bedingt hilfreich, schließlich musste dazu der Typ bereits vorab bekannt sein und ihr hättet das Objekt auch einfach per
Mit generischer Programmierung zeigt sich ein weiteres Einsatzfeld, welches sich jedoch mit einer entsprechenden Einschränkung des Typparameters auch anderweitig lösen lässt und für mehr Unterstützung des Typsystems sorgt, da ihr für eure Zwecke weitere Einschränkungen (wie beispielsweise Schnittstellen) angeben könnt:
Activator
-Klasse.Als Basis für das Beispiel soll folgende triviale Klasse dienen:
Beispielklasse
Hiervon können wir nun dynamisch ein Objekt erzeugen:
01020304050607080910111213141516
public class Person { public string FirstName { get; set; }
public string LastName { get; set; }
public Person() {}
public Person(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; }}
Objekt dynamisch erzeugen
Dieses Vorgehen ist jedoch nur in Ausnahmefällen zu empfehlen, da ihr schließlich die Vorteile der statischen Typisierung größtenteils verliert. Es bietet sich daher je nach Anwendungsfall die Verwendung von Schnittstellen (z. B. bei Plugins) oder die Verwendung generischer Programmierung (z. B. zur internen Abstraktion) an.01020304
Activator.CreateInstance(Type.GetType("Person"), new[] { "Holger", "Stehle"});
Die in diesem Beitrag vorgestellte Klasse bietet auch eine Variante mit Typparameter an: Diese Funktionalität ist in der Praxis zur "normalen" Entwicklung jedoch nur bedingt hilfreich, schließlich musste dazu der Typ bereits vorab bekannt sein und ihr hättet das Objekt auch einfach per
new
erzeugen können.Mit generischer Programmierung zeigt sich ein weiteres Einsatzfeld, welches sich jedoch mit einer entsprechenden Einschränkung des Typparameters auch anderweitig lösen lässt und für mehr Unterstützung des Typsystems sorgt, da ihr für eure Zwecke weitere Einschränkungen (wie beispielsweise Schnittstellen) angeben könnt:
Keine Werbung
Hin und wieder werde ich darauf angesprochen, warum ich mit diesem Blog und meinen anderen Seiten nicht ein wenig Geld verdiene. Dazu erreichen mich vereinzelt – neben sehr vielen unseriösen – auch ernsthafte Angebote.
Ich halte grundsätzlich nicht viel von Werbung als Einkommensquelle für sich. Ich verdiene mit Softwareentwicklung seit vielen Jahren meinen Lebensunterhalt und habe überhaupt kein Problem damit, für ordentliche Arbeit eine angemessene Gegenleistung zu verlangen. Aber sowohl diese Webpräsenz als auch die meisten anderen meiner Projekte sind Privatvergnügen. Das kostet mich monatlich etwa 90 € und ist für ein Hobby völlig in Ordnung.
Insofern gibt es hier auch zukünftig keinerlei bezahlte Werbung. Was ich aber durchaus mache und womit ich auch gar kein Problem habe: Wenn mir Dienstleistungen oder Produkte ernsthaft gefallen, dann mache ich dafür auch – unbezahlte – Werbung. Nicht zuletzt behandelt dieser Blog überwiegend Beiträge zur .NET-Technologie mit C#, womit beispielsweise sehr viele Verweise zu Microsoft gehen (die meine "Werbung" aber auch nicht nötig haben).
Ich bin aber auch ernsthaft davon überzeugt, dass C# eine außerordentlich gelungene Programmiersprache ist.
Ich halte grundsätzlich nicht viel von Werbung als Einkommensquelle für sich. Ich verdiene mit Softwareentwicklung seit vielen Jahren meinen Lebensunterhalt und habe überhaupt kein Problem damit, für ordentliche Arbeit eine angemessene Gegenleistung zu verlangen. Aber sowohl diese Webpräsenz als auch die meisten anderen meiner Projekte sind Privatvergnügen. Das kostet mich monatlich etwa 90 € und ist für ein Hobby völlig in Ordnung.
Insofern gibt es hier auch zukünftig keinerlei bezahlte Werbung. Was ich aber durchaus mache und womit ich auch gar kein Problem habe: Wenn mir Dienstleistungen oder Produkte ernsthaft gefallen, dann mache ich dafür auch – unbezahlte – Werbung. Nicht zuletzt behandelt dieser Blog überwiegend Beiträge zur .NET-Technologie mit C#, womit beispielsweise sehr viele Verweise zu Microsoft gehen (die meine "Werbung" aber auch nicht nötig haben).
Ich bin aber auch ernsthaft davon überzeugt, dass C# eine außerordentlich gelungene Programmiersprache ist.

Project links
-
BitStadt – Stadtportal
Berlin · Hamburg · Amsterdam -
CCC – Fahrplan
Schedules for the CCCongress
Categories / Archive | Übersicht
- PHP functions in C# (136)
- Dictionary (257)
Tags
.NET · ADO.NET · Work · ASP.NET MVC · Blog · C# · Generics · Society · Computer Science · Java · LINQ · Logic · Mathematics · Network · PHP · Project · Security · Software development · Studies · Technics · Theory · Web design · WPF