Enumerations in C#
Während man in anderen Programmiersprachen (wie beispielsweise PHP) eine Sammlung von Konstanten bemühen muss, um zumindest so etwas ähnliches wie einen Aufzählungstypen zu definieren, bietet uns C# hierfür eine komfortable und zugleich typsichere Lösung mittels
Häufig finden derartige Aufzählungen im Rahmen von Optionen für Methodenaufrufe Verwendung; auch im .NET-Framework begegnet ihr diesen sehr häufig (z. B. bei Dateioperationen mit der Enumeration
):
Dazu passen wir zuerst einmal unsere Aufzählung an, da wir zu diesem Zwecke Zweierpotenzen als Werte benötigen und geben auch gleich das Attribut mit an. Der späteren Bequemlichkeit wegen, erstellen wir auch noch einen weiteren Wert
enum
an.Häufig finden derartige Aufzählungen im Rahmen von Optionen für Methodenaufrufe Verwendung; auch im .NET-Framework begegnet ihr diesen sehr häufig (z. B. bei Dateioperationen mit der Enumeration
FileMode
). Als Beispiel soll hier das Recht eines Benutzers dienen. Zuerst definieren wir dazu eine entsprechende Enumeration:
Enumeration "Permission" mit den Rechten "Lesen", "Schreiben" und "Löschen"
Als nächstes erstellen wir eine (sehr minimalistische) Benutzer-Klasse, welche eine zu unserer Rechte-Enumeration kompatible Eigenschaft besitzt:
0102030405
public enum Permission { Read, Write, Delete}
Klasse "User" mit Eigenschaft für Benutzerrecht
Jetzt können wir auch schon eine Benutzer-Instanz erzeugen und ein Recht zuweisen, beispielsweise "Lesen":
Das Prinzip entspricht soweit grundsätzlich also dem Vorgehen wie bei jedem anderen Datentypen (→ allgemeinere Informationen) auch. Insbesondere können wir der Eigenschaft 010203040506
public class User { public Permission UserPermission { get; set; }}
UserPermission
z. B. nicht versehentlich einen Wert einer Aufzählung "Farbe" oder "Geschlecht" zuweisen. Nun wäre es noch praktisch, wenn wir auch auf ein spezifisches Benutzerrecht prüfen könnten – also implementieren wir eine entsprechende Methode in der Benutzer-Klasse:
Methode zur Rechteprüfung in "User"
Die Verwendung gestaltet sich nun denkbar einfach (ich schreibe es der Vollständigkeit wegen dennoch auf 010203
public bool CheckPermission(Permission permission) { return (this.UserPermission == permission);}

Rechteprüfung
Soweit können wir glaube ich zufrieden sein. Einen kleinen Schönheitsfehler gibt es jedoch: Wenn wir voraussetzen, dass ein Benutzer mit reinen Schreibrechten noch nichts löschen darf, so müssten wir ihm zwei Rechte zuweisen, wenn er es doch können soll. Wir könnten also eine Rechteliste führen – oder wir bedienen uns der Bitarithmetik und des 0102030405
if(du.CheckPermission(Permission.Write)) { // Recht vorhanden} else { // Recht NICHT vorhanden}
Flags
-Attributs (→ weitere Details zur Verwendung) und bringen beide Rechte in nur einem Feld unter.Dazu passen wir zuerst einmal unsere Aufzählung an, da wir zu diesem Zwecke Zweierpotenzen als Werte benötigen und geben auch gleich das Attribut mit an. Der späteren Bequemlichkeit wegen, erstellen wir auch noch einen weiteren Wert
ReadWrite
, welchen wir mit einem bitweisen ODER aus Read
und Write
definieren:
Enumeration "Permission" mit Attribut und eigenen Werten versehen, sowie Erweiterung um "ReadWrite"
Darüber hinaus müssen wir unsere Prüfmethode geringfügig anpassen:
01020304050607
[Flags]public enum Permission { Read = 1, Write = 2, Delete = 4, ReadWrite = (Read | Write)}
Methode zur Rechteprüfung in "User" erweitern
Nun können wir wieder ein Objekt erzeugen und erhalten die erwarteten Ergebnisse:
010203
public bool CheckPermission(Permission permission) { return ((this.UserPermission & permission) == permission);}
Benutzer mit Rechten erzeugen und prüfen
Eine derartige Vorgehensweise findet auch innerhalb des .NET-Frameworks Verwendung, z. B. bei Dateioperationen mit der Enumeration 01020304050607080910111213
// Benutzer mit Lese- und Schreibrecht erzeugenUser du = new User() { UserPermission = (Permission.Read | Permission.Write) // – oder auch - UserPermission = Permission.ReadWrite};
// Rechte prüfen (einige Beispiele)du.CheckPermission(Permission.Read); // truedu.CheckPermission(Permission.Write); // truedu.CheckPermission(Permission.Delete); // falsedu.CheckPermission(Permission.ReadWrite); // truedu.CheckPermission(Permission.Read | Permission.Delete); // false
FileAccess
. Statistics for Website
I made a small statistics page to have some sort of summary for my web pages and their feedback. If you like, you're encouraged to have a look, too.
Search Engine Optimisation
Vor einer Weile habe ich ein Angebot zur Suchmaschinenoptimierung (SEO, Search Engine Optimization) meiner Projektseite für die dt. Übersetzung der Lua-Referenz erhalten. Daran wird eigentlich schon recht klar, dass es hier nur wenig um die eigentlichen Inhalte der Seite geht. Die meisten Besucher kommen nämlich – naheliegenderweise – über den offiziellen Link der Lua-Webpräsenz und ebenfalls sehr viele bereits über Suchmaschinen. Für die breite Masse dürfte das Angebot dieser Seite nicht interessant sein, so dass eine weitere Verbreitung gar nicht notwendig ist. Werbung soll es dort selbstverständlich ebenfalls auch zukünftig nicht geben.
Es gibt auf jeden Fall sinnvolle Methoden zur "Suchmaschinenoptimierung" (wobei ich hier breiter fassen würde auf "Optimierung zur automatisierten Verarbeitung der Inhalte"). Dazu gehören Metadaten und eine semantische Struktur des Quelltextes der Webpräsenz. Dies können Suchmaschinen beispielsweise zur Darstellung eines passenden Titels und einer treffenden Kurzbeschreibung verwenden.
Ein nicht unerheblicher Anteil der Branche beschäftigt sich jedoch damit, zweifelhafte "Linkfarmen" aufzubauen, nicht im Zusammenhang mit dem eigentlichen Thema des Auftritts stehende Verknüpfungen herzustellen oder gleich direkt schlichten Spam zu betreiben, was trotz der Bemühungen großer Suchmaschinen-Anbieter dennoch ab und an zu völlig unpassenden Ergebnissen zu einer Recherche führt. Leider scheint man davon mit praktisch keinem technischen Fachwissen und wenig Aufwand sogar recht gut leben zu können, wenn man sich die Angebote einmal genauer ansieht. Die tatsächliche Auswirkung derartiger Angebote ist teilweise ebenfalls fragwürdig. Zudem finde ich es schade, dass es dadurch inhaltlich wirklich interessante Seiten schwerer haben, gefunden zu werden.
Mein einfacher, kostenloser Tipp an alle Betreiber von Webpräsenzen: Sorgt für ansprechend und sorgfältig aufbereitete Themen, dezente und vor allem passende Werbung (wenn ihr ein Thema toll auf euren Seiten beschreibt, dürft ihr darauf sicherlich bei den meisten Blogs oder Foren verweisen, wenn es um dieses Thema geht
) und der Rest ergibt sich meist von alleine, insbesondere in Zeiten von Facebook, Twitter und ähnlichen Plattformen dauert das auch gar nicht mehr so lange.
Es gibt auf jeden Fall sinnvolle Methoden zur "Suchmaschinenoptimierung" (wobei ich hier breiter fassen würde auf "Optimierung zur automatisierten Verarbeitung der Inhalte"). Dazu gehören Metadaten und eine semantische Struktur des Quelltextes der Webpräsenz. Dies können Suchmaschinen beispielsweise zur Darstellung eines passenden Titels und einer treffenden Kurzbeschreibung verwenden.
Ein nicht unerheblicher Anteil der Branche beschäftigt sich jedoch damit, zweifelhafte "Linkfarmen" aufzubauen, nicht im Zusammenhang mit dem eigentlichen Thema des Auftritts stehende Verknüpfungen herzustellen oder gleich direkt schlichten Spam zu betreiben, was trotz der Bemühungen großer Suchmaschinen-Anbieter dennoch ab und an zu völlig unpassenden Ergebnissen zu einer Recherche führt. Leider scheint man davon mit praktisch keinem technischen Fachwissen und wenig Aufwand sogar recht gut leben zu können, wenn man sich die Angebote einmal genauer ansieht. Die tatsächliche Auswirkung derartiger Angebote ist teilweise ebenfalls fragwürdig. Zudem finde ich es schade, dass es dadurch inhaltlich wirklich interessante Seiten schwerer haben, gefunden zu werden.
Mein einfacher, kostenloser Tipp an alle Betreiber von Webpräsenzen: Sorgt für ansprechend und sorgfältig aufbereitete Themen, dezente und vor allem passende Werbung (wenn ihr ein Thema toll auf euren Seiten beschreibt, dürft ihr darauf sicherlich bei den meisten Blogs oder Foren verweisen, wenn es um dieses Thema geht

Properties in C#
C# besitzt eine – meiner Meinung nach – äußerst elegante Implementierung für Akzessoren. Während es beispielsweise in Java üblich ist, nach dem Muster
Dies stellt einerseits die Kapselung der internen Daten sicher, vermeidet darüber hinaus jedoch eine Sammlung dutzender Zugiffsmethoden neben den eigentlichen Operationen einer Klasse. Sollte man lediglich "Standardzugriff" benötigen, wird einem dies besonders einfach gemacht – doch dazu später noch etwas mehr.
Als kleines Beispiel dazu wollen wir eine Klasse
Der Zugriff auf diese Daten ist nun ganz einfach möglich:
getEigenschaft()
(und setEigenschaft(…)
) zu verfahren, kombiniert C# Felder und Zugriffsmethoden zu sog. Properties.Dies stellt einerseits die Kapselung der internen Daten sicher, vermeidet darüber hinaus jedoch eine Sammlung dutzender Zugiffsmethoden neben den eigentlichen Operationen einer Klasse. Sollte man lediglich "Standardzugriff" benötigen, wird einem dies besonders einfach gemacht – doch dazu später noch etwas mehr.
Als kleines Beispiel dazu wollen wir eine Klasse
Person
entwickeln, welche den Vor- und Nachnamen einer Person aufnehmen kann:
Klasse "Person" mit Eigenschaften (manuelle Implementierung)
Wie man sieht, erstellen wir dazu private Felder für die Daten und definieren dann die Eigenschaft (per Konvention mit einem Großbuchstaben beginnend) mit den entsprechenden Zugriffsmethoden (010203040506070809101112131415161718192021
public class Person { private string firstName; public string FirstName { get { return this.firstName; } set { this.firstName = value; } }
private string lastName; public string LastName { get { return this.lastName; } set { this.lastName = value; } }}
get
und set
). Der Parameter value
wird implizit zur Verfügung gestellt und enthält den jeweils zugewiesenen Wert.Der Zugriff auf diese Daten ist nun ganz einfach möglich:
Zugriff auf Eigenschaften der Klasse "Person"
Innerhalb der Zugriffsmethoden kann beispielsweise Validierungslogik untergebracht werden. Das bloße Zuweisen und Abfragen ohne besondere zusätzliche Arbeit ist jedoch auch noch deutlich kompakter möglich – C# implementiert die Zugriffsmethoden dann automatisch. Sogar die interne Eigenschaft kann man sich sparen:
0102030405060708091011
// Zuweisung nach ObjekterzeugungPerson ich = new Person();
ich.FirstName = "Holger"; // Abfrage liefert "Holger"ich.LastName = "Stehle"; // Abfrage liefert "Stehle"
// Zuweisung per ObjektinitialisierungPerson ich = new Person() { FirstName = "Holger", LastName = "Stehle"}; /* Abfrage-Resultate wie oben */
Klasse "Person" mit Eigenschaften (automatische Implementierung)
Das Verhalten ist nun wie in unserer vorherigen Klasse, die Verwendung entsprechend ebenfalls identisch. Eine feinere Abstimmung der Zugriffsebenen ist ebenfalls möglich. Weitere Details zur Verwendung finden sich im MSDN. 0102030405060708091011
public class Person { public string FirstName { get; set; }
public string LastName { get; set; }}
Release allocated Resources in C#
Dank verwaltetem Code und automatischer Speicherbereinigung muss man sich bei C# zumeist nicht explizit darum kümmern, angeforderte Ressourcen wieder freizugeben. An manchen Stellen kann dies jedoch notwendig sein: Dies ist beispielsweise der Fall, wenn nicht verwaltete oder externe Ressourcen (z. B. Dateien, Datenbanken) involviert sind.
Zur Freigabe von Ressourcen sollte die entsprechende
Zur Freigabe von Ressourcen sollte die entsprechende
Dispose()
-Methode aufgerufen werden, welche Objekte zur Verfügung stellen, welche IDisposable
implementieren. Dies kann beispielsweise wie folgt passieren:
Ressourcen explizit freigeben
Es gibt jedoch noch eine elegantere Variante, und zwar mit Hilfe der 0102030405060708091011
Class obj = new Class();
try { /** * Anwendungs-Code **/} finally { if(obj != null) { obj.Dispose(); }}
using
-Anweisung:
Ressourcen implizit freigeben (empfohlen)
Durch dieses Vorgehen werden die Ressourcen automatisch nach Verlassen des Gültigkeitsbereichs freigegeben; dazu wird im Hintergrund folgender Code generiert:
0102030405
using(Class obj = new Class()) { /** * Anwendungs-Code **/}
Generierter Code zur Freigabe der Ressource
Zu beachten gilt, dass der 01020304050607080910111213
{ Class obj = new Class();
try { /** * Anwendungs-Code **/ } finally { if(obj != null) { ((IDisposable) obj).Dispose(); } }}
using
-Block – wie bereits durch die umschließenden geschweiften Klammern zu sehen – einen eigenen Gültigkeitsbereich darstellt, was demnach bei Variablendeklaration und -verwendung berücksichtigt werden muss. 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