Suche: ABI

PHP-Funktionen in C# (noch nicht) als Programmbibliothek 👍 👎

Meine beispielhaften PHP-Funktionen in C# erfreuen sich gewisser Beliebtheit, sodass mich mittlerweile schon ein paar mal die Frage erreicht hat, ob ich diese nicht als Programmbibliothek zur Verfügung stellen möchte.

Aus technischer Sicht wäre das tatsächlich kein Problem und grundsätzlich sogar mit überschaubarem Aufwand automatisierbar. Ich habe daher auch selbst schon einmal mit dem Gedanken der Veröffentlichung als Paket gespielt, dennoch möchte ich erst einmal Abstand davon nehmen und zwar vor allem aus folgenden Gründen:
  • Design

    Die Umsetzung der Methoden (Bezeichner, Datentypen, Parameter) ist stark an PHP angelehnt, sprich ist soweit möglich identisch zu den gleichnamigen PHP-Funktionen. Diese Umsetzung widerspricht jedoch in nahezu allen Fällen in vielerlei Hinsicht den .NET-Guidelines für Programmbibliotheken und auch die Datentypen entsprechen oftmals nicht den bei C# für den jeweiligen Einsatzzweck üblichen.

  • Qualität

    Die Umsetzungen sollen einen Ansatz bzw. Tipps liefern, entsprechen jedoch in einigen Fällen nicht einer Qualität, die einen sofortigen und ungeprüften Einsatz in Produktionsumgebungen ermöglicht. Dies wäre für eine tatsächliche Veröffentlichung jedoch zwingend erforderlich. Darüber hinaus wären an einigen Stellen Optimierungen für den effizienten Einsatz in echten Projekten durchaus sinnvoll.

Dennoch stimme ich natürlich grundsätzlich zu, dass die Implementierungen einige praktische Funktionen anbieten, die in PHP durchaus üblich sind, in C# standardmäßig jedoch nicht ohne Weiteres zur Verfügung stehen. Daher werde ich an einer entsprechenden Programmbibliothek arbeiten, die ausschließlich solche Funktionalität in stabiler Qualität zur Verfügung stellt. Einen konkreten Zeitplan kann und möchte ich derzeit jedoch noch nicht nennen.

Versionierung (Ergänzung: Alpha und Beta) 👍 👎

Ergänzend zu meinem älteren Beitrag zur Versionierung erreichte mich die Frage, wie ich es mit Alpha- und Beta-Versionen (und ggf. weiteren Unterscheidungen) bei den Entwicklungsstadien von Anwendungen halte.

Sofern ich unfertige (Haupt-)Versionen vorab veröffentliche, verwende ich lediglich die beiden bereits genannten Merkmale. Mit separaten Freigabekandidaten arbeite ich üblicherweise nicht und unterscheide wie folgt:

  • Alpha: 1, 2, …

    Dieses Merkmal bedeutet für die Version ein weitestgehend vollständig lauffähiges Programm, von dem es mir sinnvoll erscheint, dass es von vielen Personen getestet wird. Bei diesem Stand steht die wichtigste Funktionalität bereits zur Verfügung; es kann jedoch zu Erweiterungen der Funktionalität kommen, sofern diese von einer gewissen Anzahl der Anwender und mir selbst als sinnvoll erachtet wird und keiner einschneidenden Änderungen bedarf. Fehler können hin und wieder in seltenen Situationen auftreten.

  • Beta: 1, 2, …

    Dieses Merkmal bedeutet für die aktuelle Version grundsätzlich das Ende funktionaler Erweiterungen. Die Anwendung läuft in den meisten Situationen möglichst fehlerfrei, sodass bereits von einer weitestgehend stabilen Anwendung zu sprechen ist. Durch die weiteren Rückmeldungen sollen nun beispielsweise noch Details der Oberfläche verbessert, Performanzoptimierungen durchgeführt und ggf. verbliebene Probleme sehr spezieller Anwendungsfälle korrigiert werden.


In allen Fällen ist mir jedoch wichtig darauf hinzuweisen, dass weder Alpha- noch Beta-Versionen aus meiner Sicht für einen sinnvollen Einsatz unbedarfter Anwender gedacht sind, sondern explizit für Experten zur Verfügung gestellt werden, die mit auftretenden Problemen professionell umzugehen wissen, um wertvolle Rückmeldung zur Entwicklung geben zu können (und nicht etwa Frust zu erzeugen). Natürlich dürfen gerne auch weniger versierte Benutzer Rückmeldungen – beispielsweise zur Benutzerführung – geben.

Ich bin also durchaus dafür, potentielle Anwender in den Entwicklungsprozess einzubeziehen, halte aber nicht viel davon, Kunden als Qualitätssicherung zu missbrauchen. Das konkrete Vorgehen kann sich natürlich bei einzelnen Projekten unterscheiden. Web-Anwendungen, die ich selbst pflege und kein Benutzer ernsthaften Schaden befürchten muss, gebe ich sehr gerne etwas früher frei (ganz zu Beginn beispielsweise auch nur für Bekannte), als Anwendungen, die der Benutzer auf eigenen Systemen einrichten und ggf. pflegen muss.

Informationen zur Internetverbindung (und mehr) 👍 👎

Ursprünglich als (äußerst) minimalistisches Tool gestartet, um die aktuelle öffentliche IP-Adresse schnell (und vor allem ohne lästige Werbung) herauszufinden, kamen mit der Zeit einige weitere Funktionen hinzu.

Da das Projekt bereits seit einiger Zeit stillschweigend unter Projekte hier auf der Webpräsenz verlinkt wurde, haben sehr viele Besucher bereits darauf zugegriffen. Mich erreichten daher auch bereits einige Anfragen, ob beispielsweise Informationen zu beliebigen IP-Adressen (statt nur zur anfragenden IP-Adresse) abgefragt werden können und die allgemeine Verwendung des Tools für eigene Zwecke überhaupt erwünscht ist.

Zuerst möchte ich offiziell festhalten, dass selbstverständlich auch ihr die Funktionalität unter debug.coders-online.net für eigene Zwecke verwenden dürft – ansonsten hätte ich das Projekt nicht ohne weitere Hinweise öffentlich eingetragen, da ich frei verfügbare Informationen und Dienste auch als eben solche betrachte. Vielmehr gibt es sogar eine textbasierte Schnittstelle zur einfachen automatisierten Verwendung. Der am häufigsten gestellten Frage, der Freigabe für beliebige IP-Adressen, stehe ich leider etwas skeptischer gegenüber. Das liegt jedoch weniger an den technischen Möglichkeiten des Tools oder meinem Willen dazu.

Das Backend, welches die Informationen für Web-Oberfläche und Schnittstelle zur Verfügung stellt, ermöglicht selbstverständlich die beliebige Angabe von IP-Adressen – ansonsten wäre das Tool auch gar nicht allgemein einsetzbar. Von mir aus dürftet ihr auf diese "interne" Funktionalität gerne ebenfalls zugreifen, ich sehe jedoch gewisse Probleme dabei. Die angezeigten Informationen, insbesondere die der Registrierungsstelle/n, sind zwar öffentlich per Whois verfügbar, in der weiteren Verwendung jedoch üblicherweise auf ein berechtigtes Interesse beschränkt – bei der derzeitigen IP-Adresse des eigenen Anschlusses ist dieses sicherlich gegeben. Ich sehe mich andernfalls jedoch grundsätzlich der Gefahr ausgesetzt, dass massenweise Abfragen zu beliebigen Adressen mit fragwürdigem Ziel erfolgen. Da ich alle meine Projekte rein privat und großteils schlicht aus Freude an der Entwicklung (mit C#) betreibe, hoffe ich auf Verständnis, dass ich mein persönliches Risiko dabei minimieren möchte. Ihr könnt die Seiten aber beispielsweise auch einfach von eurem Server aus aufrufen.

Ich kann jedoch bereits darauf hinweisen, dass ähnliche Möglichkeiten bald auch für weitere Ziele zur Verfügung stehen werden: Im Rahmen eines Monitoring-Projekts, welches sich derzeit noch in einer frühen Entwicklungsphase befindet, können einige Funktionen auch auf eigene Webseiten und Server Anwendung finden. Selbst betriebene Server dürfen – nach einer entsprechenden Freischaltung – sogar besonders umfassend geprüft werden.

Zum Abschluss möchte ich noch die derzeit verfügbaren Funktionen kurz zusammenfassen:
  • Verbindung

    Auf der Startseite erfahrt ihr eure öffentliche IP-Adresse mit entsprechender Typisierung (IPv4, IPv6). Es wird versucht, die IP-Adresse in einen Hostnamen aufzulösen, welcher üblicherweise eine Bezeichnung mit Hinweis auf euren Anbieter enthält. Darüber hinaus werden Informationen zur Verschlüsselung (ihr könnt die Webseiten auch per HTTPS aufrufen) angezeigt und ihr habt die Möglichkeit, weitere Informationen zur IP-Adresse bei der zuständigen Registrierungsstelle abzufragen.

  • System

    Auf dieser Seite werden einige serverseitig ermittelbare Informationen zu eurem Browser und Betriebssystem angezeigt: Browser und dessen Version, die verwendete HTTP-Version, Do Not Track-Flag und Betriebssystem inkl. Version. Darüber hinaus werden die in eurem Browser konfigurierten Sprachen nach Priorität aufgelistet.

  • Tools

    Hier stehen einige weitere Abfragemöglichkeiten zur Verfügung. So kann beispielsweise die Latenz der Verbindung oder die Route zum Server bestimmt werden. Ihr könnt außerdem eure IP-Adresse auf Einträge in DNS-Blacklisten prüfen und häufig verwendete Ports des Systems überprüfen.

  • Kopfzeilen

    Auf dieser Unterseite werden alle von eurem Client zum Server gesendeten Kopfzeilen etwas aufbereitet dargestellt. Eine völlig unbearbeitete Ausgabe erhaltet ihr – wie auch in allen anderen Fällen – über die Schnittstelle. Das ist insbesondere dann praktisch, wenn ihr eigene HTTP-Funktionalität umsetzt und die gesendeten Felder prüfen möchtet.

  • Fähigkeiten

    Diese Informationen werden von HttpBrowserCapabilities zur Verfügung gestellt.

Die Webpräsenz ist auf Deutsch, Englisch und Niederländisch verfügbar; die Einstellung wird vom Browser bezogen. Vorschläge zu weiteren Funktionen und Meldungen zu Fehlern werden jederzeit gerne per Tracker angenommen.

Aufzählungswert per Zeichenkette ermitteln 👍 👎

Vor sehr langer Zeit habe ich bereits einen Artikel zu Enumerationen in C# geschrieben, an welchen ich indirekt anknüpfen möchte. Oftmals steht man im Bereich der Softwareentwicklung vor dem Problem der Interoperabilität, da mehrere – bisweilen äußerst unterschiedliche – Systeme zusammenarbeiten müssen.

Ein klassischer Fall im Bereich der Webentwicklung ist die Zusammenarbeit aus Anwendung und Datenbank, beispielsweise hier im Blog zwischen der Programmiersprache C# mit ASP.NET MVC-Framework und MySQL-Datenbank. Etwas konkreter soll es darum gehen, C#-Aufzählungstypen zusammen mit MySQL-ENUMs zu verwenden, welche grundsätzlich erst einmal als bloße Zeichenketten zu behandeln sind. Für das folgende Beispiel nehmen wir an, dass eine Tabelle user existiert, die eine Spalte state vom Typ ENUM('ACTIVE','INACTIVE','LOCKED') enthält.

Unter Verwendung des ADO.NET Entity Framework würde beim Database First-Ansatz eine entsprechende Klasse user mit der Eigenschaft state vom Typ string erzeugt. Da es sich um eine partielle Klasse handelt, erweitern wir diese um eine neue Eigenschaft State. Diese soll anschließend die automatische Konvertierung für state übernehmen und ermöglicht uns im Programmcode einen typsicheren Zugriff auf den Status des Benutzers:
Aufzählungstyp UserState anlegen
0102030405
public enum UserState {    Active,    Inactive,    Locked}
Erweiterung der Klasse user
010203040506070809
public partial class user {    public UserState State {        get {            return (UserState) Enum.Parse(typeof(UserState), this.state, true);        }        set {            this.state = value.ToString().ToUpper();        }    }
Die Verwendung gestaltet sich nun – mit beiden Eigenschaften – wie gewohnt komfortabel:
Verwendung
0102030405060708091011121314151617
user dbUser = new user() {    State = UserState.Active};  // üblicherweise aus Datenbank ermittelt

string state = dbUser.state; // "ACTIVE"UserState userState = dbUser.State; // Active
dbUser.State = UserState.Inactive;

state = dbUser.state; // "INACTIVE"userState = dbUser.State; // Inactive
dbUser.state = "LOCKED";

state = dbUser.state; // "LOCKED"userState = dbUser.State; // Locked
Weitere Informationen zu den Enum.Parse-Methoden finden sich wie üblich im MSDN. Es lohnt sich außerdem ein Blick auf die Enum.TryParse(…)-Methoden mit generischem Typ-Parameter.

Rundung in C# (und PHP) 👍 👎

Rundung erscheint auf den ersten Blick so selbstverständlich, dass so mancher geneigt scheint, sich darüber gar keine großen Gedanken zu machen. Beim Ab- und Aufrunden mit Methoden wie Math.Floor und Math.Ceiling gibt es auch tatsächlich keine großen Überraschungen bei den meisten Programmiersprachen:
Auf- und Abrunden
010203040506070809
  // Abrundungdouble floor1 = Math.Floor(1.3);  // 1double floor2 = Math.Floor(1.5);  // 1double floor3 = Math.Floor(1.7);  // 1  // Aufrundungdouble ceiling1 = Math.Ceiling(1.3);  // 2double ceiling2 = Math.Ceiling(1.5);  // 2double ceiling3 = Math.Ceiling(1.7);  // 2
Spannend wird es jedoch beim allgemeineren Rundungsverfahren mit Math.Round, bei welchem sich das Verhalten standardmäßig zu dem unterscheiden kann, was man beispielsweise aus der Schule als kaufmännisches Runden oder vom Standardverhalten von round aus PHP kennt. Der Unterschied liegt konkret beim Rundungsverhalten an der Ziffer 5:
Rundungsverhalten an der Ziffer "5"
01020304050607
double rounded11 = Math.Round(2.3);  // 2double rounded12 = Math.Round(2.5);  // 2 (!)double rounded13 = Math.Round(2.7);  // 3
double rounded21 = Math.Round(7.3); // 7double rounded22 = Math.Round(7.5); // 8double rounded23 = Math.Round(7.7); // 8
Die Ursache für dieses für manche möglicherweise überraschende Verhalten liegt darin begründet, dass bei C# das mathematische Rundungsverfahren zur Anwendung kommt, welches in so einem Fall standardmäßig die Rundung zur nächsten geraden Ziffer vorschreibt, anstatt pauschal aufzurunden. Das Anliegen dabei ist es, statistische Verzerrungen durch ausschließliches Aufrunden an dieser Stelle zu vermeiden. Dies ist in jedem Fall bei der Interoperabilität mit anderen Systemen, die auf eine gleiche Datenbasis zugreifen, zu berücksichtigen.

Sowohl bei C# als auch bei PHP lässt sich dieses Verhalten jedoch manuell anpassen (und dadurch nötigenfalls angleichen), indem man unter C# einen Wert der Enumeration MidpointRounding oder unter PHP eine der Konstanten PHP_ROUND_HALF_* an die entsprechende Methode/Funktion zur Rundung übergibt.

12

Projektverweise

Kategorien / Archiv  |  Übersicht RSS-Feed

Schlagworte

Suche