<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Dani.NET</title>
    <link>http://blog.nettigkeiten.ch/</link>
    <description />
    <language>en-us</language>
    <copyright>Dani Meier</copyright>
    <lastBuildDate>Sat, 01 Dec 2007 14:22:17 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>dani.meier@gmail.com</managingEditor>
    <webMaster>dani.meier@gmail.com</webMaster>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=6de4012a-2dbb-4fb6-9ccc-c1065b62e76e</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,6de4012a-2dbb-4fb6-9ccc-c1065b62e76e.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,6de4012a-2dbb-4fb6-9ccc-c1065b62e76e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=6de4012a-2dbb-4fb6-9ccc-c1065b62e76e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Heute schiessen ja die Adventskalender auf den verschiedensten WebSites geradezu aus
dem Boden. Einer, dessen Besuch sich wirklich lohnt, ist auf <a href="http://entwickler-press.de/" target="_blank">entwickler-press.de</a> zu
finden. Dort gibts nämlich jeden Tag ein eBook gratis und franko zum Download, ja
man muss sich noch nicht mal registrieren.
</p>
        <p>
Heute gibts <a href="http://www.amazon.de/Managed-DirectX-Einstieg-professioneller-Einsatz/dp/3939084174/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1196518914&amp;sr=8-1" target="_blank">Managed
Direct X und C#</a>. 
</p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=6de4012a-2dbb-4fb6-9ccc-c1065b62e76e" />
      </body>
      <title>Adventskalender bei entwickler-press.de</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,6de4012a-2dbb-4fb6-9ccc-c1065b62e76e.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/12/01/AdventskalenderBeiEntwicklerpressde.aspx</link>
      <pubDate>Sat, 01 Dec 2007 14:22:17 GMT</pubDate>
      <description>&lt;p&gt;
Heute schiessen ja die Adventskalender auf den verschiedensten WebSites geradezu aus
dem Boden. Einer, dessen Besuch sich wirklich lohnt, ist auf &lt;a href="http://entwickler-press.de/" target="_blank"&gt;entwickler-press.de&lt;/a&gt; zu
finden. Dort gibts nämlich jeden Tag ein eBook gratis und franko zum Download, ja
man muss sich noch nicht mal registrieren.
&lt;/p&gt;
&lt;p&gt;
Heute gibts &lt;a href="http://www.amazon.de/Managed-DirectX-Einstieg-professioneller-Einsatz/dp/3939084174/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1196518914&amp;amp;sr=8-1" target="_blank"&gt;Managed
Direct X und C#&lt;/a&gt;. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=6de4012a-2dbb-4fb6-9ccc-c1065b62e76e" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,6de4012a-2dbb-4fb6-9ccc-c1065b62e76e.aspx</comments>
      <category>Lesefutter</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=5ba60655-bc47-487f-a88b-00b75d6de670</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,5ba60655-bc47-487f-a88b-00b75d6de670.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,5ba60655-bc47-487f-a88b-00b75d6de670.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=5ba60655-bc47-487f-a88b-00b75d6de670</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://keepass.info/" target="_blank">KeePass</a> war mir unter Windows ein
ständiger Begleiter und passte für mich perfekt zur Verwaltung meiner Passwörter.
Mittlerweile ist meine Passwort-Datenbank auch schon recht angewachsen... blöd nur,
dass es das Ding nur für Windows gibt.
</p>
        <p>
Trotzdem - mal googlen... aah... 
</p>
        <p>
          <a title="KeePassX" href="http://www.keepassx.org" target="_blank">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="183" alt="keypassx" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/KeePassundUbuntu_6FAA/keypassx_3.png" width="182" border="0" />
          </a>
        </p>
        <p>
KeePassX, eine Portierung von KeePass für Linux- und Mac-Systeme - und ja, es kann
die KeePass-Datenbanken lesen - und auch umgekehrt. So kann ich also weiterhin die
bestehende Datenbank nutzen und diese unter Linux mit KeePassX und unter Windows mit
KeePass lesen.
</p>
        <p>
          <a href="http://keepass.info/" target="_blank">KeePass</a>
          <br />
          <a href="http://www.keepassx.org/" target="_blank">KeePassX</a>
        </p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=5ba60655-bc47-487f-a88b-00b75d6de670" />
      </body>
      <title>KeePass und Ubuntu</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,5ba60655-bc47-487f-a88b-00b75d6de670.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/12/01/KeePassUndUbuntu.aspx</link>
      <pubDate>Sat, 01 Dec 2007 14:09:51 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://keepass.info/" target="_blank"&gt;KeePass&lt;/a&gt; war mir unter Windows ein
ständiger Begleiter und passte für mich perfekt zur Verwaltung meiner Passwörter.
Mittlerweile ist meine Passwort-Datenbank auch schon recht angewachsen... blöd nur,
dass es das Ding nur für Windows gibt.
&lt;/p&gt;
&lt;p&gt;
Trotzdem - mal googlen... aah... 
&lt;/p&gt;
&lt;p&gt;
&lt;a title="KeePassX" href="http://www.keepassx.org" target="_blank"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="183" alt="keypassx" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/KeePassundUbuntu_6FAA/keypassx_3.png" width="182" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
KeePassX, eine Portierung von KeePass für Linux- und Mac-Systeme - und ja, es kann
die KeePass-Datenbanken lesen - und auch umgekehrt. So kann ich also weiterhin die
bestehende Datenbank nutzen und diese unter Linux mit KeePassX und unter Windows mit
KeePass lesen.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://keepass.info/" target="_blank"&gt;KeePass&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://www.keepassx.org/" target="_blank"&gt;KeePassX&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=5ba60655-bc47-487f-a88b-00b75d6de670" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,5ba60655-bc47-487f-a88b-00b75d6de670.aspx</comments>
      <category>Software</category>
      <category>Ubuntu</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=f10e4f61-f502-48ce-8f27-58486e4866ca</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,f10e4f61-f502-48ce-8f27-58486e4866ca.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,f10e4f61-f502-48ce-8f27-58486e4866ca.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=f10e4f61-f502-48ce-8f27-58486e4866ca</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Nachdem ich schon seit längerem ein Doppelleben führte, habe ich mich nun definitiv
entschieden! Seit der Version 7.10 bin ich vollständig auf <a href="http://www.ubuntu.com/">Ubuntu</a> umgestiegen.
Wieso denn das?
</p>
        <p>
Durch mein Studium musste ich mich zwangsweise das eine oder andere Mal mit Linux
auseinandersetzen, und je länger ich damit arbeitete, desto mehr stieg meine Begeisterung
dafür. Die Arbeit damit ist einfach effizienter, die typischen Slow-Downs die ich
unter Windows immer wieder hatte (Vista kann man fast als andauernden Slow-Down bezeichnen
;-) ) bleiben unter Linux eine wirkliche Seltenheit.
</p>
        <p>
Dazu kommt noch, dass es eine ganze Menge an kleinen feinen Tools gibt, die natürlich
allesamt Open-Source sind.
</p>
        <p>
Natürlich komme ich, als .NET-Entwickler, nicht um Windows rum - aber dafür gibts
ja VMWare. 
</p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=f10e4f61-f502-48ce-8f27-58486e4866ca" />
      </body>
      <title>Ich geh fremd!</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,f10e4f61-f502-48ce-8f27-58486e4866ca.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/11/28/IchGehFremd.aspx</link>
      <pubDate>Wed, 28 Nov 2007 20:34:33 GMT</pubDate>
      <description>&lt;p&gt;
Nachdem ich schon seit längerem ein Doppelleben führte, habe ich mich nun definitiv
entschieden! Seit der Version 7.10 bin ich vollständig auf &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; umgestiegen.
Wieso denn das?
&lt;/p&gt;
&lt;p&gt;
Durch mein Studium musste ich mich zwangsweise das eine oder andere Mal mit Linux
auseinandersetzen, und je länger ich damit arbeitete, desto mehr stieg meine Begeisterung
dafür. Die Arbeit damit ist einfach effizienter, die typischen Slow-Downs die ich
unter Windows immer wieder hatte (Vista kann man fast als andauernden Slow-Down bezeichnen
;-) ) bleiben unter Linux eine wirkliche Seltenheit.
&lt;/p&gt;
&lt;p&gt;
Dazu kommt noch, dass es eine ganze Menge an kleinen feinen Tools gibt, die natürlich
allesamt Open-Source sind.
&lt;/p&gt;
&lt;p&gt;
Natürlich komme ich, als .NET-Entwickler, nicht um Windows rum - aber dafür gibts
ja VMWare. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=f10e4f61-f502-48ce-8f27-58486e4866ca" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,f10e4f61-f502-48ce-8f27-58486e4866ca.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=0f8c5e89-f17f-4d0f-b1f4-e0d4524ffb71</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,0f8c5e89-f17f-4d0f-b1f4-e0d4524ffb71.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,0f8c5e89-f17f-4d0f-b1f4-e0d4524ffb71.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=0f8c5e89-f17f-4d0f-b1f4-e0d4524ffb71</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Mit knapp 2 Monaten Verspätung folgt nun also der zweite Teil dieser kleinen Serie
:-)
</p>
        <p>
Die IDE ist das meist täglich gebrauchte Werkzeug eines jeden Entwicklers. Unter .NET
ist das mit Abstand am meisten verbreitete Exemplar dieser Gattung Visual Studio in
den verschiedenen Ausprägungen. Wie bereits in Teil 1 geschrieben, erachte ich die
Wahl der IDE als sekundär, Hauptsache der Entwickler findet sich damit zu Recht -
also vergleichbar mit den Kochmessern eines Küchenchefs :-)
</p>
        <p>
Dieser Artikel wird zeigen, wie man mittels Visual Studio 2008 seine Projekte mit
UnitTests testet. UnitTests sollten genauso ein Selbstverständnis für einen Entwickler
sein, wie auch alle anderen Punkte dieser Serie. Ich möchte hier nicht ins Detail
gehen, das machen andere schon sehr gut - trotzdem aber die wichtigsten Punkte, um
was es beim Unit-Testing geht. Zuerst also etwas Theorie.
</p>
        <h3>Definition
</h3>
        <p>
Für ne schlaue Definition muss wiedermal <a href="http://en.wikipedia.org/wiki/Unit_tests">Wikipedia</a> herhalten:
</p>
        <p>
          <em>"(...) unit testing is a procedure used to validate that individual units of source
code are working properly. A unit is the smallest testable part of an application."</em>
        </p>
        <p>
Also - man testet den kleinst-möglichen testbaren Teil einer Applikation - und das
ist per Definition in einer OO-Anwendung natürlich die Methode. Dieser scheinbar unspektakuläre
Satz, beeinhaltet schon einige der Grundsätze von Unit Tests.
</p>
        <ul>
          <li>
Jeder Unit-Test testet genau eine Methode, nicht mehr und nicht weniger. Es werden
also keine ganzen Abläufe (z.B. Abfolge von Method-Calls) getestet. 
</li>
          <li>
Das Resultat eines Unit-Tests sagt aus, ob die Methode (und nur genau die) gemäss
dem definierten Testfall korrekt funktioniert.</li>
        </ul>
        <p>
Unit-Tests sollten immer möglichst einfach gehalten werden, dies reduziert das Risiko
von Fehler im Test selbst.
</p>
        <h3>Test-Driven Development
</h3>
        <p>
Im Zusammenhang mit Unit-Tests wird oftmals von Test-Driven Development (TDD) gesprochen.
Wie der Name schon sagt, geht es dabei darum, mittels Tests zur eigentlichen Implementation
zu kommen. Neue Funktionen werden stets gegen die <strong>zuvor</strong> definierten
Testfälle implementiert und getestet. Eine Funktion gilt dann als implementiert, wenn
diese alle für sie definierten Testfälle erfolgreich durchlaufen kann. In diesem Zusammenhang
ebenfalls wichtige Konzepte sind
</p>
        <ul>
          <li>
KISS - Keep it simple, stupid 
</li>
          <li>
YAGNI - You ain't gonna need it</li>
        </ul>
        <p>
Wichtiger Punkt im TDD ist also, nur genau das zu implementieren, was auch gefordert
wird - und alles was gefordert wird, muss als Testfall hinterlegt sein. Jede Funktion
die zusätzlich implementiert wird, quasi als gutgemeinten Bonus, ist nicht getestet
(zumindest durch Unit-Tests) und stellt daher eine Verletzung dieser Prinzipien dar.
</p>
        <h3>Die Regeln des Test-Driven Development
</h3>
        <p>
Der Ablauf beim TDD erscheint vielen Entwicklern anfangs etwas umständlich und gewöhnungsbedürftig.
Auch scheinen die Regeln teils etwas überbestimmt. Trotzdem hat jede dieser Regeln
ihre Berechtigung.
</p>
        <ol>
          <li>
            <strong>Schreibe den Test</strong>
            <br />
Hier werden viele bereits stutzig. Den Test vor der eigentlichen Methode schreiben?
Genau! Denn die Methode soll ja vom Test abhängen und nicht umgekehrt. Andersrum besteht
immer die Gefahr, dass der Test um die Methode gebaut wird. Man testet das, was man
weiss das die Methode kann - und nicht was sie können sollte. 
</li>
          <li>
            <strong>Implementiere die Methode so, dass sie (und der zuvor definierte Test) gerade
mal kompiliert, der Test aber fehlschlägt</strong>
            <br />
Dieser Punkt wird oft ignoriert, da er so trivial erscheint. Der Punkt, dass der Test
aber immer zuerst fehlschlagen soll, ist sehr zentral, da auch ein Test - wie jedes
andere Stück Software auch - prinzipiell Fehler enthalten kann. Das heisst, der Test
könnte immer erfolgreich sein, obwohl der Case gar nicht erfüllt ist. Dieser Punkt
ist also quasi der Test des Tests. 
</li>
          <li>
            <strong>Implementiere die Methode so, dass sie den Testfall besteht</strong>
            <br />
Nun gehts also ans Eingemachte, die Methode soll ihre Implementation erhalten, und
zwar so, dass sie den zuvor geschriebenen Test erfolgreich durchläuft. Wichtig dabei
ist, dass hier noch nicht die ultimative Super-Lösung gebaut werden soll. Es soll
in erster Linie mal einfach funktionieren. Nachdem in Punkt 2 ja getestet wurde, dass
der Test fehlschlägt wenn er soll, muss jetzt ja auch mal gezeigt werden, dass er
zu einer funktionierenden Methode auch sein "OK" gibt. 
</li>
          <li>
            <strong>Refactor</strong>
            <br />
Nun wird die laufende Lösung von Punkt 4 mittels Refactoring "verschönert". Der Test
muss danach natürlich immer noch korrekt durchlaufen werden. 
</li>
          <li>
            <strong>Starte wieder bei Punkt 1</strong>
            <br />
Eine Methode hat in den seltensten Fällen nur einen Testfall. Da die Fälle sehr einfach
gehalten werden sollen, gibt es hier meist ein ganzes Set von Tests pro Funktion.
Dieser Punkt streicht den iterativen Ansatz dieser Methodik hervor. Die Implementation
wächst also iterativ mit jedem Testfall, und ist genau dann fertig, wenn keine weiteren
Fälle mehr zu definieren sind und alle definierten Fälle erfolgreich abgeschlossen
werden können.</li>
        </ol>
        <p>
Wieso denn nun das ganze? Die Vorteile die aus dieser Vorgehensweise entstehen sollten
für sich sprechen:
</p>
        <ul>
          <li>
            <strong>Fehlerfreie Software?</strong>
            <br />
Nicht ganz - aber man weiss zumindest, und kann auch jederzeit nachprüfen, dass eine
Funktion mit den definierten Testfällen klar kommt. Natürlich heisst das noch lange
nicht, dass damit die Software korrekt funktioniert oder gar fehlerfrei ist. Jedoch
kann man von einem gewissen Grad an Korrektheit ausgehen. Sollten trotzdem Fehler
auftreten, waren die Testfälle nicht ausreichend. 
</li>
          <li>
            <strong>Entspannte Änderungen</strong>
            <br />
Jeder kennt das, man muss an einer Software etwas ändern und man ist sich vielleicht
nicht ganz 100%ig über die Konsequenzen im Klaren. Side-Effects treten ja meist an
den Stellen auf, an denen man sie am wenigsten vermutet. Kann der Entwickler jedoch
nach seiner Änderung auf eine Fülle von erfolgreich abgearbeiteten Testfälle blicken,
wird das sein Vertrauen merklich steigern. Auch hier gilt aber natürlich Vorsicht,
die Änderung kann trotzdem Fehler verursachen! Evtl. müssen für die Änderung auch
neue Tests eingeführt werden. 
</li>
          <li>
            <strong>Dokumentation</strong>
            <br />
Auch diese Situation ist wohl den meisten bekannt - man hat eine Methode vor sich
und kann irgendwie nicht so greifen, was diese überhaupt genau macht. Die "erklärenden"
Sätze in den Kommentaren machen das ganze auch nicht einfacher. Die Testfälle hingegen
zeigen mit sehr übersichtlichem und einfachem Code, was die Methode zu erfüllen hat. 
</li>
          <li>
            <strong>Lose Kopplung</strong>
            <br />
Dies kommt praktisch gratis mit TDD mit. Denn wer so vorgeht, wird automatisch wenig
Abhängigkeiten erzeugen. Abhängigkeiten sind immer irgendwo problematisch beim testen
- da wird man sich also hüten.</li>
        </ul>
        <h3>Die Krux mit den Abhängigkeiten
</h3>
        <p>
Wie bereits geschrieben, sind Abhängigkeiten ein grundsätzliches Problem beim Unit-Testing.
Man stelle sich zum Beispiel vor, man möchte eine Methode einer Datenbankzugriffsklasse
testen. Beim schlichten Aufruf dieser Methode wird automatisch auch die Datenbank
aufgerufen. Was test man so nun? Funktioniert das Db-Statement? Ist die Datenbank
erreichbar? Oder doch nur ob die Funktion korrekt funktioniert? Ja genau - alles zusammen,
und doch wieder nichts. Wenn was schief geht, ist nicht klar warum. Daraus ergeben
sich einige Grundregeln, die man beim Schreiben der Tests beachten sollte:
</p>
        <p>
Ein Unit-Test sollte nie
</p>
        <ul>
          <li>
I/O-Funktionalität aufrufen (Filesysteme, Datenbanken, Netzwerk... alles tabu) 
</li>
          <li>
auf ein Konfigurations-File angewiesen sein 
</li>
          <li>
von anderen Unit-Tests abhängig sein. Jeder Test muss für sich allein funktionieren.</li>
        </ul>
        <p>
Solche Abhängigkeiten werden mit Hilfe von <a href="http://en.wikipedia.org/wiki/Mock_object">Mock-Objekten</a> nachgebaut.
Hierzu wird nächstens ein eigener kleiner Artikel folgen.
</p>
        <p>
Wer all dies berücksichtigt - wird glücklich mit TDD - da leg ich meine Hand ins Feuer
:-)
</p>
        <h3>TDD mit Visual Studio 2008
</h3>
        <p>
Das neue Visual Studio (wie auch das alte :-) ) bietet alles, was man zu TDD benötigt.
Zur Veranschaulichung ziehen wir mal so ein Szenario durch. Als Beispiel dient uns
eine Applikation, die beliebige Zeichenketten durch verschiedene Sortieralgorithmen
sortieren kann - so zum Beispiel mit QuickSort, ein beliebter "Divide and Conquer"-Algorithmus.
</p>
        <p>
Als Ausgangslage dient uns folgender Aufbau der Applikation:
</p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/solutionexplorer_start_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="solutionexplorer_start" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/solutionexplorer_start_thumb.png" width="219" border="0" />
          </a>
        </p>
        <p>
Program.cs beinhaltet etwas Code zur Verarbeitung der Eingabe sowie die schlussendliche
Ausgabe des Resultates. ISortAlgorithm ist ein Interface, welches die Schnittstellen
eines Sortieralgorithmus' vorgibt - nämlich:
</p>
        <pre class="code">
          <span style="color: blue">public interface </span>
          <span style="color: #2b91af">ISortAlgorithm </span>{ <span style="color: blue">string </span>Sort(<span style="color: blue">string </span>toSort);
}</pre>
        <p>
        </p>
        <p>
Nun haben wir ja vorhin einen schönen Ablauf definiert, also sehen wir mal ob der
was taugt:
</p>
        <p>
          <strong>Punkt 1 - Test schreiben:</strong>
        </p>
        <p>
An dieser Stelle erlaube ich mir bereits die erste kleine Abweichung obiger Regel.
Und zwar erstelle ich mir jeweils aus Bequemlichkeit bereits die Klasse sowie den
Methodenrumpf bevor ich den Test schreibe. Das hat den Vorteil, das man beim Test
schreiben auf IntelliSense zurückgreifen kann und nicht alles komisch rot unterstrichen
erscheint. Ausserdem kann man sich das Gerüst für die Tests gleich in Visual Studio
generieren lassen.
</p>
        <p>
Ich erstelle also die Klasse QuickSortAlgorithm und implementiere das obige Interface
ISortingAlgorithm. Das ist's dann aber auch schon. Danach genügt ein Rechtsklick ins
Fenster zum Erstellen des Test-Projektes.
</p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/createtestproject_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="290" alt="createtestproject" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/createtestproject_thumb.png" width="284" border="0" />
          </a>
        </p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/createtestproject_dialog_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="createtestproject_dialog" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/createtestproject_dialog_thumb.png" width="404" border="0" />
          </a>
        </p>
        <p>
In dem generierten File findet sich dann eine Methode SortTest. Dies ist nun also
unser Test, dessen Logik wir nun noch zu definieren haben.
</p>
        <pre class="code">       [<span style="color: #2b91af">TestMethod</span>()] <span style="color: blue"> public
void </span>SortTest() { <span style="color: #2b91af">QuickSortAlgorithm </span>target
= <span style="color: blue">new </span><span style="color: #2b91af">QuickSortAlgorithm</span>(); <span style="color: green">//
TODO: Initialize to an appropriate value </span><span style="color: blue">string </span>toSort
= <span style="color: blue">string</span>.Empty; <span style="color: green">// TODO:
Initialize to an appropriate value </span><span style="color: blue">string </span>expected
= <span style="color: blue">string</span>.Empty; <span style="color: green">// TODO:
Initialize to an appropriate value </span><span style="color: blue">string </span>actual;
actual = target.Sort(toSort); <span style="color: #2b91af">Assert</span>.AreEqual(expected,
actual); <span style="color: #2b91af">Assert</span>.Inconclusive(<span style="color: #a31515">"Verify
the correctness of this test method."</span>); }</pre>
        <p>
        </p>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
Das TestMethod-Attribut gibt an, dass es sich bei der Methode um einen Test handelt.
Dies ist notwendig, damit Visual Studio damit zu Recht kommt.
</p>
        <p>
Um dies zu tun, muss man sich natürlich über die Anforderungen im Klaren sein. Unit-Tests
sind WhiteBox-Tests - der Entwickler weiss also von der Implementation, dies ist auch
nötig, wie wir später noch sehen werden. Also die Anforderung ist, dass wir der Methode
einen String übergeben können und dieser sortiert zurück kommt. Entsprechend passen
wir den Test an:
</p>
        <pre class="code">        [<span style="color: #2b91af">TestMethod</span>()] <span style="color: blue">public
void </span>SortTest() { <span style="color: #2b91af">QuickSortAlgorithm </span>target
= <span style="color: blue">new </span><span style="color: #2b91af">QuickSortAlgorithm</span>(); <span style="color: blue">string </span>toSort
= <span style="color: #a31515">"bda"</span>; <span style="color: blue">string </span>expected
= <span style="color: #a31515">"abd"</span>; <span style="color: blue">string </span>actual;
actual = target.Sort(toSort); <span style="color: #2b91af">Assert</span>.AreEqual(expected,
actual); }</pre>
        <p>
Sehr schlicht und einfach also das ganze. Gut - und nun zu Punkt 2.
</p>
        <p>
          <strong>Punkt 2 - Methode implementieren, dass der Test fehlschlägt</strong>
        </p>
        <p>
Einfach, aber wichtig - also, wir geben einen Wert zurück, der den Test dazu veranlassen
müsste, fehlzuschlagen - also zum Beispiel einen Leerstring.
</p>
        <p>
Nun lassen wir den Test ein erstes Mal laufen um zu schauen, ob das Erwartete auch
wirklich eintrifft. Ein Weg den Test zu starten ist wiederum über das Kontextmenü
der Testmethode:
</p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/runtests_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="190" alt="runtests" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/runtests_thumb.png" width="244" border="0" />
          </a>
        </p>
        <p>
Und erhält folgendes Resultat:
</p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/testresult_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="101" alt="testresult" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/testresult_thumb.png" width="404" border="0" />
          </a>
        </p>
        <p>
Wenn das Resultat hier auf "Passed" wäre, wüsste man nun, dass der Test noch fehlerhaft
ist, da er offensichtlich falsche Daten also korrekt klassifizierte.
</p>
        <p>
 
</p>
        <p>
Auf die restlichen Punkte muss hier nicht genauer eingegangen werden. Nun geht es
einfach noch darum, die Implementation korrekt zu machen, und weitere Testfälle zu
definieren, die sicherstellen, dass der Algorithmus korrekt funktioniert. 
</p>
        <p>
Weitere Testfälle wären zum Beispiel:
</p>
        <ul>
          <li>
weitere Strings die korrekt sortiert werden müssen (spezielle Daten!), erwartet korrekt
sortierte Rückgaben 
</li>
          <li>
ein Leerstring als Übergabe, erwartet einen Leerstring als Rückgabe 
</li>
          <li>
null als Übergabe, erwartet eine NullReferenceException 
</li>
          <li>
usw.</li>
        </ul>
        <p>
Das Beispiel mit einigen definierten Testfällen gibt's zum Download.
</p>
        <p>
 
</p>
        <h3>Code Coverage
</h3>
        <p>
Die Code Coverage gibt an, wieviel Prozent der Code-Statements durch einen Test abgedeckt
werden. Dieser Wert sagt zwar prinzipiell nicht sehr viel aus, man sollte die Coverage
aber dennoch immer etwas im Auge behalten. Ziel sollte ein Wert jenseits der 90%-Marke
sein.
</p>
        <p>
Mit Visual Studio lässt sich die Code Coverage sehr einfach messen. Hierzu müssen
aber zuerst die Assemblies ausgewählt werden, auf denen die Messung stattfinden soll.
Das entsprechende Menu findet man hier:
</p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/editconfig_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="169" alt="editconfig" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/editconfig_thumb.png" width="404" border="0" />
          </a>
        </p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/editconfig2_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="356" alt="editconfig2" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/editconfig2_thumb.png" width="504" border="0" />
          </a>
        </p>
        <p>
Danach kann man, nachdem die Tests durchgeführt wurden, das Code Coverage-Fenster
öffnen und sich die Resultate zu Gemüte führen.
</p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/showcov_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="282" alt="showcov" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/showcov_thumb.png" width="404" border="0" />
          </a>
        </p>
        <p>
In dem Fenster kann man sich dann auch gleich anzeigen lassen, welche Zeilen durch
einen Test abgedeckt werden und welche nicht. So kann man seine Testfälle optimieren.
</p>
        <p>
          <a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/resultscov_2.png">
            <img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="442" alt="resultscov" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/resultscov_thumb.png" width="604" border="0" />
          </a>
        </p>
        <p>
Dies zeigt nun auch, wieso Unit-Tests eben WhiteBox-Tests sein müssen. Damit die Testfälle
alle Verzweigungen einer Methode berücksichtigen kann, muss der Entwickler des Testfalls
wissen, wie die Methode implementiert ist.
</p>
        <p>
Natürlich sagt eine CodeCoverage von 100% nicht sonderlich viel aus - es ist weder
ein Qualitätsmerkmal für den Code noch für die Testfälle. Es geht dabei mehr darum,
zu entdecken, ob gewisse Code-Teile nicht getestet werden.
</p>
        <p>
 
</p>
        <h3>Fazit
</h3>
        <p>
Unit Tests und TDD sind ein grosses und wichtiges Thema. Visual Studio ermöglicht
einen komfortablen Einsatz. Seit der 2008-Version, weden Unit-Tests bereits in der
Professional-Variante unterstützt. Allerdings geht es auch ohne - Tools hierfür gibt
es wie Sand am Meer. Erwähnt seien hier <a href="http://www.nunit.org/">NUnit</a>, <a href="http://www.ncover.com/">NCover</a> und <a href="http://www.testdriven.net/">TestDriven.Net</a> (kostenpflichtig).
</p>
        <p>
Viel braucht es also nicht, um Test-Driven entwickeln zu können. Trotzdem stellt sich
der Anfang als eher harzig heraus, da es doch eine etwas andere Denk- und Vorgehensweise
erfordert. Die Vorteile überwiegen aber doch klar, und wer sich einmal daran gewöhnt
hat, wird es nicht mehr missen wollen.
</p>
        <p>
Und hier noch das Beispiel-Programm zum Download: 
<br /><a href="http://blog.nettigkeiten.ch/content/binary/StringSort.zip">StringSort.zip
(57.99 KB)</a></p>
        <h3>Referenzen
</h3>
        <ul>
          <li>
            <a href="http://en.wikipedia.org/wiki/Unit_tests">Unit Tests (Wikipedia)</a>
          </li>
          <li>
            <a href="http://en.wikipedia.org/wiki/Test-driven_development">Test-Driven Development
(Wikipedia)</a>
          </li>
        </ul>
        <h3>Literatur
</h3>
        <ul>
          <li>
            <a href="http://www.manning.com/osherove/">The art of unit testing, Roy Osherove</a>
          </li>
          <li>
            <a href="http://www.amazon.com/Test-Driven-Development-Microsoft-NET-Professional/dp/0735619484/ref=sr_1_5?ie=UTF8&amp;s=books&amp;qid=1196279765&amp;sr=1-5">Test-Driven
Development in .NET, James W. Newkirk, Alexei A. Vorontsov</a>
          </li>
          <li>
            <a href="http://www.amazon.com/Professional-Software-Testing-Visual-Studio/dp/0470149787/ref=sr_1_7?ie=UTF8&amp;s=books&amp;qid=1196279765&amp;sr=1-7">Professional
Software Testing with Visual Studio 2005 VS, Tom Arnold, Dominic Hopton, Andy Leonard,
Mike Frost</a>
          </li>
        </ul>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=0f8c5e89-f17f-4d0f-b1f4-e0d4524ffb71" />
      </body>
      <title>Eine professionelle Entwicklungsinfrastruktur f&amp;uuml;r (fast) lau (Teil 2 von 5) - IDE</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,0f8c5e89-f17f-4d0f-b1f4-e0d4524ffb71.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/11/28/EineProfessionelleEntwicklungsinfrastrukturFuumlrFastLauTeil2Von5IDE.aspx</link>
      <pubDate>Wed, 28 Nov 2007 19:33:53 GMT</pubDate>
      <description>&lt;p&gt;
Mit knapp 2 Monaten Verspätung folgt nun also der zweite Teil dieser kleinen Serie
:-)
&lt;/p&gt;
&lt;p&gt;
Die IDE ist das meist täglich gebrauchte Werkzeug eines jeden Entwicklers. Unter .NET
ist das mit Abstand am meisten verbreitete Exemplar dieser Gattung Visual Studio in
den verschiedenen Ausprägungen. Wie bereits in Teil 1 geschrieben, erachte ich die
Wahl der IDE als sekundär, Hauptsache der Entwickler findet sich damit zu Recht -
also vergleichbar mit den Kochmessern eines Küchenchefs :-)
&lt;/p&gt;
&lt;p&gt;
Dieser Artikel wird zeigen, wie man mittels Visual Studio 2008 seine Projekte mit
UnitTests testet. UnitTests sollten genauso ein Selbstverständnis für einen Entwickler
sein, wie auch alle anderen Punkte dieser Serie. Ich möchte hier nicht ins Detail
gehen, das machen andere schon sehr gut - trotzdem aber die wichtigsten Punkte, um
was es beim Unit-Testing geht. Zuerst also etwas Theorie.
&lt;/p&gt;
&lt;h3&gt;Definition
&lt;/h3&gt;
&lt;p&gt;
Für ne schlaue Definition muss wiedermal &lt;a href="http://en.wikipedia.org/wiki/Unit_tests"&gt;Wikipedia&lt;/a&gt; herhalten:
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;"(...) unit testing is a procedure used to validate that individual units of source
code are working properly. A unit is the smallest testable part of an application."&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Also - man testet den kleinst-möglichen testbaren Teil einer Applikation - und das
ist per Definition in einer OO-Anwendung natürlich die Methode. Dieser scheinbar unspektakuläre
Satz, beeinhaltet schon einige der Grundsätze von Unit Tests.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Jeder Unit-Test testet genau eine Methode, nicht mehr und nicht weniger. Es werden
also keine ganzen Abläufe (z.B. Abfolge von Method-Calls) getestet. 
&lt;li&gt;
Das Resultat eines Unit-Tests sagt aus, ob die Methode (und nur genau die) gemäss
dem definierten Testfall korrekt funktioniert.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Unit-Tests sollten immer möglichst einfach gehalten werden, dies reduziert das Risiko
von Fehler im Test selbst.
&lt;/p&gt;
&lt;h3&gt;Test-Driven Development
&lt;/h3&gt;
&lt;p&gt;
Im Zusammenhang mit Unit-Tests wird oftmals von Test-Driven Development (TDD) gesprochen.
Wie der Name schon sagt, geht es dabei darum, mittels Tests zur eigentlichen Implementation
zu kommen. Neue Funktionen werden stets gegen die &lt;strong&gt;zuvor&lt;/strong&gt; definierten
Testfälle implementiert und getestet. Eine Funktion gilt dann als implementiert, wenn
diese alle für sie definierten Testfälle erfolgreich durchlaufen kann. In diesem Zusammenhang
ebenfalls wichtige Konzepte sind
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
KISS - Keep it simple, stupid 
&lt;li&gt;
YAGNI - You ain't gonna need it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Wichtiger Punkt im TDD ist also, nur genau das zu implementieren, was auch gefordert
wird - und alles was gefordert wird, muss als Testfall hinterlegt sein. Jede Funktion
die zusätzlich implementiert wird, quasi als gutgemeinten Bonus, ist nicht getestet
(zumindest durch Unit-Tests) und stellt daher eine Verletzung dieser Prinzipien dar.
&lt;/p&gt;
&lt;h3&gt;Die Regeln des Test-Driven Development
&lt;/h3&gt;
&lt;p&gt;
Der Ablauf beim TDD erscheint vielen Entwicklern anfangs etwas umständlich und gewöhnungsbedürftig.
Auch scheinen die Regeln teils etwas überbestimmt. Trotzdem hat jede dieser Regeln
ihre Berechtigung.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Schreibe den Test&lt;/strong&gt;
&lt;br&gt;
Hier werden viele bereits stutzig. Den Test vor der eigentlichen Methode schreiben?
Genau! Denn die Methode soll ja vom Test abhängen und nicht umgekehrt. Andersrum besteht
immer die Gefahr, dass der Test um die Methode gebaut wird. Man testet das, was man
weiss das die Methode kann - und nicht was sie können sollte. 
&lt;li&gt;
&lt;strong&gt;Implementiere die Methode so, dass sie (und der zuvor definierte Test) gerade
mal kompiliert, der Test aber fehlschlägt&lt;/strong&gt;
&lt;br&gt;
Dieser Punkt wird oft ignoriert, da er so trivial erscheint. Der Punkt, dass der Test
aber immer zuerst fehlschlagen soll, ist sehr zentral, da auch ein Test - wie jedes
andere Stück Software auch - prinzipiell Fehler enthalten kann. Das heisst, der Test
könnte immer erfolgreich sein, obwohl der Case gar nicht erfüllt ist. Dieser Punkt
ist also quasi der Test des Tests. 
&lt;li&gt;
&lt;strong&gt;Implementiere die Methode so, dass sie den Testfall besteht&lt;/strong&gt;
&lt;br&gt;
Nun gehts also ans Eingemachte, die Methode soll ihre Implementation erhalten, und
zwar so, dass sie den zuvor geschriebenen Test erfolgreich durchläuft. Wichtig dabei
ist, dass hier noch nicht die ultimative Super-Lösung gebaut werden soll. Es soll
in erster Linie mal einfach funktionieren. Nachdem in Punkt 2 ja getestet wurde, dass
der Test fehlschlägt wenn er soll, muss jetzt ja auch mal gezeigt werden, dass er
zu einer funktionierenden Methode auch sein "OK" gibt. 
&lt;li&gt;
&lt;strong&gt;Refactor&lt;/strong&gt;
&lt;br&gt;
Nun wird die laufende Lösung von Punkt 4 mittels Refactoring "verschönert". Der Test
muss danach natürlich immer noch korrekt durchlaufen werden. 
&lt;li&gt;
&lt;strong&gt;Starte wieder bei Punkt 1&lt;/strong&gt;
&lt;br&gt;
Eine Methode hat in den seltensten Fällen nur einen Testfall. Da die Fälle sehr einfach
gehalten werden sollen, gibt es hier meist ein ganzes Set von Tests pro Funktion.
Dieser Punkt streicht den iterativen Ansatz dieser Methodik hervor. Die Implementation
wächst also iterativ mit jedem Testfall, und ist genau dann fertig, wenn keine weiteren
Fälle mehr zu definieren sind und alle definierten Fälle erfolgreich abgeschlossen
werden können.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Wieso denn nun das ganze? Die Vorteile die aus dieser Vorgehensweise entstehen sollten
für sich sprechen:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fehlerfreie Software?&lt;/strong&gt;
&lt;br&gt;
Nicht ganz - aber man weiss zumindest, und kann auch jederzeit nachprüfen, dass eine
Funktion mit den definierten Testfällen klar kommt. Natürlich heisst das noch lange
nicht, dass damit die Software korrekt funktioniert oder gar fehlerfrei ist. Jedoch
kann man von einem gewissen Grad an Korrektheit ausgehen. Sollten trotzdem Fehler
auftreten, waren die Testfälle nicht ausreichend. 
&lt;li&gt;
&lt;strong&gt;Entspannte Änderungen&lt;/strong&gt;
&lt;br&gt;
Jeder kennt das, man muss an einer Software etwas ändern und man ist sich vielleicht
nicht ganz 100%ig über die Konsequenzen im Klaren. Side-Effects treten ja meist an
den Stellen auf, an denen man sie am wenigsten vermutet. Kann der Entwickler jedoch
nach seiner Änderung auf eine Fülle von erfolgreich abgearbeiteten Testfälle blicken,
wird das sein Vertrauen merklich steigern. Auch hier gilt aber natürlich Vorsicht,
die Änderung kann trotzdem Fehler verursachen! Evtl. müssen für die Änderung auch
neue Tests eingeführt werden. 
&lt;li&gt;
&lt;strong&gt;Dokumentation&lt;/strong&gt;
&lt;br&gt;
Auch diese Situation ist wohl den meisten bekannt - man hat eine Methode vor sich
und kann irgendwie nicht so greifen, was diese überhaupt genau macht. Die "erklärenden"
Sätze in den Kommentaren machen das ganze auch nicht einfacher. Die Testfälle hingegen
zeigen mit sehr übersichtlichem und einfachem Code, was die Methode zu erfüllen hat. 
&lt;li&gt;
&lt;strong&gt;Lose Kopplung&lt;/strong&gt;
&lt;br&gt;
Dies kommt praktisch gratis mit TDD mit. Denn wer so vorgeht, wird automatisch wenig
Abhängigkeiten erzeugen. Abhängigkeiten sind immer irgendwo problematisch beim testen
- da wird man sich also hüten.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Die Krux mit den Abhängigkeiten
&lt;/h3&gt;
&lt;p&gt;
Wie bereits geschrieben, sind Abhängigkeiten ein grundsätzliches Problem beim Unit-Testing.
Man stelle sich zum Beispiel vor, man möchte eine Methode einer Datenbankzugriffsklasse
testen. Beim schlichten Aufruf dieser Methode wird automatisch auch die Datenbank
aufgerufen. Was test man so nun? Funktioniert das Db-Statement? Ist die Datenbank
erreichbar? Oder doch nur ob die Funktion korrekt funktioniert? Ja genau - alles zusammen,
und doch wieder nichts. Wenn was schief geht, ist nicht klar warum. Daraus ergeben
sich einige Grundregeln, die man beim Schreiben der Tests beachten sollte:
&lt;/p&gt;
&lt;p&gt;
Ein Unit-Test sollte nie
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
I/O-Funktionalität aufrufen (Filesysteme, Datenbanken, Netzwerk... alles tabu) 
&lt;li&gt;
auf ein Konfigurations-File angewiesen sein 
&lt;li&gt;
von anderen Unit-Tests abhängig sein. Jeder Test muss für sich allein funktionieren.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Solche Abhängigkeiten werden mit Hilfe von &lt;a href="http://en.wikipedia.org/wiki/Mock_object"&gt;Mock-Objekten&lt;/a&gt; nachgebaut.
Hierzu wird nächstens ein eigener kleiner Artikel folgen.
&lt;/p&gt;
&lt;p&gt;
Wer all dies berücksichtigt - wird glücklich mit TDD - da leg ich meine Hand ins Feuer
:-)
&lt;/p&gt;
&lt;h3&gt;TDD mit Visual Studio 2008
&lt;/h3&gt;
&lt;p&gt;
Das neue Visual Studio (wie auch das alte :-) ) bietet alles, was man zu TDD benötigt.
Zur Veranschaulichung ziehen wir mal so ein Szenario durch. Als Beispiel dient uns
eine Applikation, die beliebige Zeichenketten durch verschiedene Sortieralgorithmen
sortieren kann - so zum Beispiel mit QuickSort, ein beliebter "Divide and Conquer"-Algorithmus.
&lt;/p&gt;
&lt;p&gt;
Als Ausgangslage dient uns folgender Aufbau der Applikation:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/solutionexplorer_start_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="solutionexplorer_start" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/solutionexplorer_start_thumb.png" width="219" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Program.cs beinhaltet etwas Code zur Verarbeitung der Eingabe sowie die schlussendliche
Ausgabe des Resultates. ISortAlgorithm ist ein Interface, welches die Schnittstellen
eines Sortieralgorithmus' vorgibt - nämlich:
&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public interface &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ISortAlgorithm &lt;/span&gt;{ &lt;span style="color: blue"&gt;string &lt;/span&gt;Sort(&lt;span style="color: blue"&gt;string &lt;/span&gt;toSort);
}&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Nun haben wir ja vorhin einen schönen Ablauf definiert, also sehen wir mal ob der
was taugt:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Punkt 1 - Test schreiben:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
An dieser Stelle erlaube ich mir bereits die erste kleine Abweichung obiger Regel.
Und zwar erstelle ich mir jeweils aus Bequemlichkeit bereits die Klasse sowie den
Methodenrumpf bevor ich den Test schreibe. Das hat den Vorteil, das man beim Test
schreiben auf IntelliSense zurückgreifen kann und nicht alles komisch rot unterstrichen
erscheint. Ausserdem kann man sich das Gerüst für die Tests gleich in Visual Studio
generieren lassen.
&lt;/p&gt;
&lt;p&gt;
Ich erstelle also die Klasse QuickSortAlgorithm und implementiere das obige Interface
ISortingAlgorithm. Das ist's dann aber auch schon. Danach genügt ein Rechtsklick ins
Fenster zum Erstellen des Test-Projektes.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/createtestproject_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="290" alt="createtestproject" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/createtestproject_thumb.png" width="284" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/createtestproject_dialog_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" alt="createtestproject_dialog" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/createtestproject_dialog_thumb.png" width="404" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
In dem generierten File findet sich dann eine Methode SortTest. Dies ist nun also
unser Test, dessen Logik wir nun noch zu definieren haben.
&lt;/p&gt;
&lt;pre class="code"&gt;       [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;()] &lt;span style="color: blue"&gt; public
void &lt;/span&gt;SortTest() { &lt;span style="color: #2b91af"&gt;QuickSortAlgorithm &lt;/span&gt;target
= &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;QuickSortAlgorithm&lt;/span&gt;(); &lt;span style="color: green"&gt;//
TODO: Initialize to an appropriate value &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;toSort
= &lt;span style="color: blue"&gt;string&lt;/span&gt;.Empty; &lt;span style="color: green"&gt;// TODO:
Initialize to an appropriate value &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;expected
= &lt;span style="color: blue"&gt;string&lt;/span&gt;.Empty; &lt;span style="color: green"&gt;// TODO:
Initialize to an appropriate value &lt;/span&gt;&lt;span style="color: blue"&gt;string &lt;/span&gt;actual;
actual = target.Sort(toSort); &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(expected,
actual); &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.Inconclusive(&lt;span style="color: #a31515"&gt;"Verify
the correctness of this test method."&lt;/span&gt;); }&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
Das TestMethod-Attribut gibt an, dass es sich bei der Methode um einen Test handelt.
Dies ist notwendig, damit Visual Studio damit zu Recht kommt.
&lt;/p&gt;
&lt;p&gt;
Um dies zu tun, muss man sich natürlich über die Anforderungen im Klaren sein. Unit-Tests
sind WhiteBox-Tests - der Entwickler weiss also von der Implementation, dies ist auch
nötig, wie wir später noch sehen werden. Also die Anforderung ist, dass wir der Methode
einen String übergeben können und dieser sortiert zurück kommt. Entsprechend passen
wir den Test an:
&lt;/p&gt;
&lt;pre class="code"&gt;        [&lt;span style="color: #2b91af"&gt;TestMethod&lt;/span&gt;()] &lt;span style="color: blue"&gt;public
void &lt;/span&gt;SortTest() { &lt;span style="color: #2b91af"&gt;QuickSortAlgorithm &lt;/span&gt;target
= &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;QuickSortAlgorithm&lt;/span&gt;(); &lt;span style="color: blue"&gt;string &lt;/span&gt;toSort
= &lt;span style="color: #a31515"&gt;"bda"&lt;/span&gt;; &lt;span style="color: blue"&gt;string &lt;/span&gt;expected
= &lt;span style="color: #a31515"&gt;"abd"&lt;/span&gt;; &lt;span style="color: blue"&gt;string &lt;/span&gt;actual;
actual = target.Sort(toSort); &lt;span style="color: #2b91af"&gt;Assert&lt;/span&gt;.AreEqual(expected,
actual); }&lt;/pre&gt;
&lt;p&gt;
Sehr schlicht und einfach also das ganze. Gut - und nun zu Punkt 2.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Punkt 2 - Methode implementieren, dass der Test fehlschlägt&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Einfach, aber wichtig - also, wir geben einen Wert zurück, der den Test dazu veranlassen
müsste, fehlzuschlagen - also zum Beispiel einen Leerstring.
&lt;/p&gt;
&lt;p&gt;
Nun lassen wir den Test ein erstes Mal laufen um zu schauen, ob das Erwartete auch
wirklich eintrifft. Ein Weg den Test zu starten ist wiederum über das Kontextmenü
der Testmethode:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/runtests_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="190" alt="runtests" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/runtests_thumb.png" width="244" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Und erhält folgendes Resultat:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/testresult_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="101" alt="testresult" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/testresult_thumb.png" width="404" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Wenn das Resultat hier auf "Passed" wäre, wüsste man nun, dass der Test noch fehlerhaft
ist, da er offensichtlich falsche Daten also korrekt klassifizierte.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Auf die restlichen Punkte muss hier nicht genauer eingegangen werden. Nun geht es
einfach noch darum, die Implementation korrekt zu machen, und weitere Testfälle zu
definieren, die sicherstellen, dass der Algorithmus korrekt funktioniert. 
&lt;/p&gt;
&lt;p&gt;
Weitere Testfälle wären zum Beispiel:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
weitere Strings die korrekt sortiert werden müssen (spezielle Daten!), erwartet korrekt
sortierte Rückgaben 
&lt;li&gt;
ein Leerstring als Übergabe, erwartet einen Leerstring als Rückgabe 
&lt;li&gt;
null als Übergabe, erwartet eine NullReferenceException 
&lt;li&gt;
usw.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Das Beispiel mit einigen definierten Testfällen gibt's zum Download.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;h3&gt;Code Coverage
&lt;/h3&gt;
&lt;p&gt;
Die Code Coverage gibt an, wieviel Prozent der Code-Statements durch einen Test abgedeckt
werden. Dieser Wert sagt zwar prinzipiell nicht sehr viel aus, man sollte die Coverage
aber dennoch immer etwas im Auge behalten. Ziel sollte ein Wert jenseits der 90%-Marke
sein.
&lt;/p&gt;
&lt;p&gt;
Mit Visual Studio lässt sich die Code Coverage sehr einfach messen. Hierzu müssen
aber zuerst die Assemblies ausgewählt werden, auf denen die Messung stattfinden soll.
Das entsprechende Menu findet man hier:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/editconfig_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="169" alt="editconfig" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/editconfig_thumb.png" width="404" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/editconfig2_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="356" alt="editconfig2" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/editconfig2_thumb.png" width="504" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Danach kann man, nachdem die Tests durchgeführt wurden, das Code Coverage-Fenster
öffnen und sich die Resultate zu Gemüte führen.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/showcov_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="282" alt="showcov" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/showcov_thumb.png" width="404" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
In dem Fenster kann man sich dann auch gleich anzeigen lassen, welche Zeilen durch
einen Test abgedeckt werden und welche nicht. So kann man seine Testfälle optimieren.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/resultscov_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="442" alt="resultscov" src="http://blog.nettigkeiten.ch/content/binary/WindowsLiveWriter/EineprofessionelleEntwicklungsinfrastruk_12147/resultscov_thumb.png" width="604" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Dies zeigt nun auch, wieso Unit-Tests eben WhiteBox-Tests sein müssen. Damit die Testfälle
alle Verzweigungen einer Methode berücksichtigen kann, muss der Entwickler des Testfalls
wissen, wie die Methode implementiert ist.
&lt;/p&gt;
&lt;p&gt;
Natürlich sagt eine CodeCoverage von 100% nicht sonderlich viel aus - es ist weder
ein Qualitätsmerkmal für den Code noch für die Testfälle. Es geht dabei mehr darum,
zu entdecken, ob gewisse Code-Teile nicht getestet werden.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;h3&gt;Fazit
&lt;/h3&gt;
&lt;p&gt;
Unit Tests und TDD sind ein grosses und wichtiges Thema. Visual Studio ermöglicht
einen komfortablen Einsatz. Seit der 2008-Version, weden Unit-Tests bereits in der
Professional-Variante unterstützt. Allerdings geht es auch ohne - Tools hierfür gibt
es wie Sand am Meer. Erwähnt seien hier &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt;, &lt;a href="http://www.ncover.com/"&gt;NCover&lt;/a&gt; und &lt;a href="http://www.testdriven.net/"&gt;TestDriven.Net&lt;/a&gt; (kostenpflichtig).
&lt;/p&gt;
&lt;p&gt;
Viel braucht es also nicht, um Test-Driven entwickeln zu können. Trotzdem stellt sich
der Anfang als eher harzig heraus, da es doch eine etwas andere Denk- und Vorgehensweise
erfordert. Die Vorteile überwiegen aber doch klar, und wer sich einmal daran gewöhnt
hat, wird es nicht mehr missen wollen.
&lt;/p&gt;
&lt;p&gt;
Und hier noch das Beispiel-Programm zum Download: 
&lt;br /&gt;
&lt;a href="http://blog.nettigkeiten.ch/content/binary/StringSort.zip"&gt;StringSort.zip
(57.99 KB)&lt;/a&gt; 
&lt;/p&gt;
&lt;h3&gt;Referenzen
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://en.wikipedia.org/wiki/Unit_tests"&gt;Unit Tests (Wikipedia)&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;Test-Driven Development
(Wikipedia)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Literatur
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.manning.com/osherove/"&gt;The art of unit testing, Roy Osherove&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://www.amazon.com/Test-Driven-Development-Microsoft-NET-Professional/dp/0735619484/ref=sr_1_5?ie=UTF8&amp;amp;s=books&amp;amp;qid=1196279765&amp;amp;sr=1-5"&gt;Test-Driven
Development in .NET, James W. Newkirk, Alexei A. Vorontsov&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://www.amazon.com/Professional-Software-Testing-Visual-Studio/dp/0470149787/ref=sr_1_7?ie=UTF8&amp;amp;s=books&amp;amp;qid=1196279765&amp;amp;sr=1-7"&gt;Professional
Software Testing with Visual Studio 2005 VS, Tom Arnold, Dominic Hopton, Andy Leonard,
Mike Frost&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=0f8c5e89-f17f-4d0f-b1f4-e0d4524ffb71" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,0f8c5e89-f17f-4d0f-b1f4-e0d4524ffb71.aspx</comments>
      <category>TDD</category>
      <category>Testing</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=785ad017-1f7f-4502-8f22-8403ead4c574</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,785ad017-1f7f-4502-8f22-8403ead4c574.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,785ad017-1f7f-4502-8f22-8403ead4c574.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=785ad017-1f7f-4502-8f22-8403ead4c574</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In dieser Artikelserie möchte ich aufzeigen, was man benötigt um eine (meiner Meinung
nach) professionelle Entwicklungsinfrastruktur aufzusetzen. Nun, wahrscheinlich hat
jeder so seine eigenen Vorstellungen davon, was unter professionell zu verstehen ist.
Gut möglich auch, dass einiges was der eine als professionell auffasst, der andere
als unnötig oder übetrieben erachtet. Nichtsdestotrotz gibt es wohl den einen
oder anderen Stützpfeiler in der Software-Entwicklung, der sich etabliert und eine
gewisse Daseinsberechtigung erarbeitet hat.
</p>
        <p>
Was ist also eine professionelle Entwicklungsinfrastruktur bzw. welche Ziele sollten
bei der Einrichtung einer solchen verfolgt werden? 
</p>
        <ul>
          <li>
Geht es einfach darum dem Entwickler Freude zu bereiten, ihm ein "gutes Gefühl" zu
vermitteln? 
</li>
          <li>
Dem Projektleiter und Kunden ein Gefühl von Sicherheit zu vermitteln? 
</li>
          <li>
Oder einfach nur das Projekt rechtzeitig und gemäss Anforderungen abzuschliessen? 
</li>
        </ul>
        <p>
Richtig - idealerweise werden alle diese Punkte (und noch einige weitere) erreicht. 
<br />
Eine gut funktionierende und unterstützende Infrastruktur ist zwar nicht die Garantie
für all das, aber zumindest bietet sie einem das Werkzeug und die Hilfsmittel, diese
Ziele zu erreichen.
</p>
        <p>
Ich werde in diesem Artikel einen Überblick über die Komponenten aufzeigen, die aus
meiner Sicht in eine Entwicklungsinfrastruktur gehören - also nicht "wäre noch nett"-Komponenten,
sondern "ohne die mach ich keinen Fingerzeig"-Komponenten. Die nächsten Artikel werden
dann jeweils detaillierter auf die einzelnen Komponenten eingehen. Die vorgestellten
Tools habe ich dabei rein subjektiv ausgewählt. Wer bessere oder einfach andere Altnernativen
bzw. Ergänzungen hat, ist angehalten diese per Kommentar mitzuteilen.
</p>
        <h3>Die IDE
</h3>
        <p>
          <em>"An integrated development environment (IDE), also known as integrated design
environment and integrated debugging environment, is a type of computer software that
assists computer programmers in developing software."</em> (<a href="http://en.wikipedia.org/wiki/Integrated_development_environment" target="_blank">Wikipedia</a>)
</p>
        <p>
Die IDE (=Integrated Development Environment) ist wohl das Tool, womit die meisten
von uns am meisten Zeit verbringen. Und doch ist es für die Erreichung unserer Ziele
wahrscheinlich das unkritischste von allen. Ob der Entwickler nun mit einer "echten"
IDE wie VS 2005 oder einfach nur mit einem simplen Texteditor wie Notepad arbeitet,
ist letztendlich seinen Angewohnheiten und Vorlieben überlassen. Für das Projektresultat
ist die Wahl der IDE bzw. des Editors also insofern wichtig, dass der Entwickler
mit seiner IDE quasi harmoniert und sie auch handhaben kann.
</p>
        <p>
Vertreter dieser Kategorie: Visual Studio, SharpDevelop, Eclipse, IntelliJ, JBoss,
etc.
</p>
        <p>
In dieser Serie werde ich Visual Studio 2005 TS einsetzen.
</p>
        <p>
Der Artikel zur IDE wird sich auf die Entwicklung von UnitTests mit VS 2005 beschränken.
</p>
        <p>
 
</p>
        <h3>Versionskontrolle
</h3>
        <p>
          <em>"Revision control (also known as version control (system) (VCS), source control
or (source) code management (SCM)) is the management of multiple revisions of the
same unit of information. It is most commonly used in engineering and software development
to manage ongoing development of digital documents like application source code, art
resources such as blueprints or electronic models and other critical information that
may be worked on by a team of people." </em>(<a href="http://en.wikipedia.org/wiki/Revision_control" target="_blank">Wikipedia</a>)
</p>
        <p>
Die SCC ist ein absolutes Muss für jeden der auch nur halbwegs professionell Software
entwickelt. Erfreulicherweise ist der Einsatz eines entsprechenden Systems auch die
Regel - aber leider bestätigen natürlich auch hier die Ausnahmen selbige. Eine gute
SCC bietet neben des impliziten BackUps der lokalen Kopie, vorallem auch den
Vorteil der Versionierung. Weiter sollte es möglich sein, Source Code auf verschiedenen
Zweigen (= Branches) voranzutreiben bzw. Tags oder Labels vom Code zu erstellen. Was
das genau ist und wie man damit umgeht, wird in Teil 3 dieser Serie besprochen.
</p>
        <p>
SCC-Systeme werden meist mit Diff- und Merging-Tools ergänzt, da dies natürlich Funktionalitäten
sind, die sich bei der täglichen Arbeit mit einer SCC notwendigerweise ergeben.
</p>
        <p>
Die Wahl der SCC ist auch hier eher unbedeutend und sollte halt einfach die jeweiligen
Bedürfnisse und Vorlieben abdecken.
</p>
        <p>
Auch hier, einige Vertreter dieser Kategorie: CVS, Subversion, Visual SourceSafe,
Sourcegear Vault
</p>
        <p>
In der Serie wird Subversion eingesetzt.
</p>
        <p>
 
</p>
        <h3>Build-Script
</h3>
        <p>
          <em>Build automation is the act of scripting or automating the process of compiling
computer source code into binary code. This automated build is in contrast to a manual
build process where a person has to perform multiple, often tedious and error prone
tasks.</em> (<a href="http://en.wikipedia.org/wiki/Build_Automation" target="_blank">Wikipedia</a>)
</p>
        <p>
Ein Build-Script ist keine eigentliche Software-Komponente, sondern halt nur ein Script.
Was das Script dann schlussendlich tun soll, ist abhängig von den Wünschen und Anforderungen
der Projektteilnehmer. Was es aber grundsätzlich natürlich immer kann bzw. können
sollte, ist das schlichte kompilieren des Codes. Als erweiterte Möglichkeiten wären
zum Beispiel folgende Punkte denkbar:
</p>
        <ul>
          <li>
Erstellung der Datenbank 
</li>
          <li>
IIS Automatisierung (virt. Directories erstellen, Konfigurationen vornehmen etc.) 
</li>
          <li>
Umgebungsabhängige Konfigurations-Dateien erstellen (Stichwort: ConnectionString) 
</li>
          <li>
Automatisierte Test-Durchführung (z.B. UnitTests) 
</li>
          <li>
SCC-Operationen 
</li>
          <li>
und und und...</li>
        </ul>
        <p>
Seit .NET 2.0 haben .NET Entwickler die grosse Erleichterung, dass jedes Solution-
bzw. Projektfile von Visual Studio 2005 selbst bereits ein MSBuild-Skript darstellt,
welches zumindest mal die Solution oder das Projekt durch einen simplen Kommandozeilen-Aufruf
von "<strong>msbuild mysolution.sln</strong>" kompilieren kann. Damit ist bereits
die wichtigste Funktion eines BuildScripts abgedeckt, mit der auch schon einiges erreicht
werden kann (z.B. automatische Kompilierung über Scheduled Tasks).
</p>
        <p>
Vertreter dieser Kategorie sind zum Beispiel das eben genannte MSBuild, (n)ant oder
auch die klassischen make-Files.
</p>
        <p>
In dieser Serie werden wir auf MSBuild setzen.
</p>
        <p>
 
</p>
        <h3>Build-Server / Continuous Integration Server
</h3>
        <p>
"<em>Continuous integration is the name that emerged in the Extreme Programming community
for the software engineering practice of immediately committing every change, no matter
how small, to a revision control system. Other developers should always work with
the latest version of the codebase.</em>" (<a href="http://en.wikipedia.org/wiki/Continuous_integration" target="_blank">Wikipedia</a>)
</p>
        <p>
Build-Server im eigentlichen Sinne sind eigentlich heutzutage recht out.In aller Munde
hingegen ist Continuous Integration oder kurz CI. Wo genau die Unterschiede sind,
wird im entsprechenden Artikel behandelt - wobei der Schwerpunkt klar auf CI-Servern
gelegt wird.
</p>
        <p>
Vertreter dieser Kategorie sind Cruise Control (.NET), Team Foundation Server, TeamCity,
Bamboo
</p>
        <p>
Wir werden uns mit Cruise Control .NET beschäftigen.
</p>
        <p>
 
</p>
        <p>
Dies war mal so ein kleiner Überblick über die Themen dieser Serie. Jeder der folgenden
Artikel wird dann ein einzelnes dieser Themengebiete genauer beleuchten. 
</p>
        <p>
Um nochmals auf die eingangs erwähnten Fragestellungen zurückzukommen:
</p>
        <ul>
          <li>
            <strong>Geht es einfach darum dem Entwickler Freude zu bereiten, ihm ein "gutes Gefühl"
zu vermitteln? 
<br /></strong>Der Entwickler wird automatisch ein gutes Gefühl erhalten. Automatisch ausgeführte
Builds, Tests etc. werden ihm stets das Gefühl verleihen, dass das Programm auf gutem
Weg ist. Allein schon die morgendliche Nachricht, dass der Nightlybuild ohne Fehler
durchgelaufen ist, wirkt hier Wunder. Im Artikel über CI werden wir aber noch einiges
weiter gehen (Nightlybuilds != CI) 
</li>
          <li>
            <strong>Dem Projektleiter und Kunden ein Gefühl von Sicherheit zu vermitteln? 
<br /></strong>Durch den Einsatz von CI können wir ein stets lauffähiges System vorweisen
(das heisst nicht das alle Funktionen bereits vollständig implementiert sind etc.).
Es gibt doch nichts Schlimmeres, als wenn der Kunde etwas sehen möchte und der Entwickler
ihn mit lauter kryptischen (aber im Entwicklungsprozess) normalen Fehlermeldungen
konfrontiert. 
</li>
          <li>
            <strong>Oder einfach nur das Projekt rechtzeitig und gemäss Anforderungen abzuschliessen? 
<br /></strong>Hierfür brauchts natürlich noch einiges mehr, als eine gute Infrastruktur
- aber ein erster Schritt ist damit getan.</li>
        </ul>
        <p>
Alle verwendeten Komponenten bis auf Visual Studio sind frei erhältlich, der Kostenpunkt
sollte also zumindest was die Lizenzkosten anbelangt keinen Grund darstellen, auf
diese wichtigen Komponenten zu verzichten - wie es mit dem Aufwand aussieht, werden
die nächsten Artikel zeigen.
</p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=785ad017-1f7f-4502-8f22-8403ead4c574" />
      </body>
      <title>Eine professionelle Entwicklungsinfrastruktur f&amp;uuml;r (fast) lau (Teil 1 von 5) - &amp;Uuml;berblick</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,785ad017-1f7f-4502-8f22-8403ead4c574.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/09/19/EineProfessionelleEntwicklungsinfrastrukturFuumlrFastLauTeil1Von5Uumlberblick.aspx</link>
      <pubDate>Wed, 19 Sep 2007 17:59:54 GMT</pubDate>
      <description>&lt;p&gt;
In dieser Artikelserie möchte ich aufzeigen, was man benötigt um eine (meiner Meinung
nach) professionelle Entwicklungsinfrastruktur aufzusetzen. Nun, wahrscheinlich hat
jeder so seine eigenen Vorstellungen davon, was unter professionell zu verstehen ist.
Gut möglich auch, dass einiges was der eine als professionell auffasst, der andere
als unnötig oder übetrieben&amp;nbsp;erachtet. Nichtsdestotrotz gibt es wohl den einen
oder anderen Stützpfeiler in der Software-Entwicklung, der sich etabliert und eine
gewisse Daseinsberechtigung erarbeitet hat.
&lt;/p&gt;
&lt;p&gt;
Was ist also eine professionelle Entwicklungsinfrastruktur bzw. welche Ziele sollten
bei der Einrichtung einer solchen verfolgt werden? 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Geht es einfach darum dem Entwickler Freude zu bereiten, ihm ein "gutes Gefühl" zu
vermitteln? 
&lt;li&gt;
Dem Projektleiter und Kunden ein Gefühl von Sicherheit zu vermitteln? 
&lt;li&gt;
Oder einfach nur das Projekt rechtzeitig und gemäss Anforderungen&amp;nbsp;abzuschliessen? 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Richtig - idealerweise werden alle diese Punkte (und noch einige weitere)&amp;nbsp;erreicht. 
&lt;br&gt;
Eine gut funktionierende und unterstützende Infrastruktur ist zwar nicht die Garantie
für all das, aber zumindest bietet sie einem das Werkzeug und die Hilfsmittel, diese
Ziele zu erreichen.
&lt;/p&gt;
&lt;p&gt;
Ich werde in diesem Artikel einen Überblick über die Komponenten aufzeigen, die aus
meiner Sicht in eine Entwicklungsinfrastruktur gehören - also nicht "wäre noch nett"-Komponenten,
sondern "ohne die mach ich keinen Fingerzeig"-Komponenten. Die nächsten Artikel werden
dann jeweils detaillierter auf die einzelnen Komponenten eingehen. Die vorgestellten
Tools habe ich dabei rein subjektiv ausgewählt. Wer bessere oder einfach andere Altnernativen
bzw. Ergänzungen hat, ist angehalten diese per Kommentar mitzuteilen.
&lt;/p&gt;
&lt;h3&gt;Die IDE
&lt;/h3&gt;
&lt;p&gt;
&lt;em&gt;"An integrated development environment (IDE), also known as integrated design
environment and integrated debugging environment, is a type of computer software that
assists computer programmers in developing software."&lt;/em&gt; (&lt;a href="http://en.wikipedia.org/wiki/Integrated_development_environment" target="_blank"&gt;Wikipedia&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
Die IDE (=Integrated Development Environment) ist wohl das Tool, womit die meisten
von uns am meisten Zeit verbringen. Und doch ist es für die Erreichung unserer Ziele
wahrscheinlich das unkritischste von allen. Ob der Entwickler nun mit einer "echten"
IDE wie&amp;nbsp;VS 2005 oder einfach nur mit einem simplen Texteditor wie Notepad arbeitet,
ist letztendlich seinen Angewohnheiten und Vorlieben überlassen. Für das Projektresultat
ist die Wahl der IDE&amp;nbsp;bzw. des&amp;nbsp;Editors also insofern wichtig, dass der Entwickler
mit seiner IDE quasi harmoniert und sie auch handhaben kann.
&lt;/p&gt;
&lt;p&gt;
Vertreter dieser Kategorie: Visual Studio,&amp;nbsp;SharpDevelop, Eclipse, IntelliJ, JBoss,
etc.
&lt;/p&gt;
&lt;p&gt;
In dieser Serie werde ich&amp;nbsp;Visual Studio 2005 TS einsetzen.
&lt;/p&gt;
&lt;p&gt;
Der Artikel zur IDE wird sich auf die Entwicklung von UnitTests mit VS 2005 beschränken.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;h3&gt;Versionskontrolle
&lt;/h3&gt;
&lt;p&gt;
&lt;em&gt;"Revision control (also known as version control (system) (VCS), source control
or (source) code management (SCM)) is the management of multiple revisions of the
same unit of information. It is most commonly used in engineering and software development
to manage ongoing development of digital documents like application source code, art
resources such as blueprints or electronic models and other critical information that
may be worked on by a team of people." &lt;/em&gt;(&lt;a href="http://en.wikipedia.org/wiki/Revision_control" target="_blank"&gt;Wikipedia&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
Die SCC ist ein absolutes Muss für jeden der auch nur halbwegs professionell Software
entwickelt. Erfreulicherweise ist der Einsatz eines entsprechenden Systems auch die
Regel - aber leider bestätigen natürlich auch hier die Ausnahmen selbige. Eine gute
SCC bietet neben des impliziten BackUps der lokalen Kopie,&amp;nbsp;vorallem auch den
Vorteil der Versionierung. Weiter sollte es möglich sein, Source Code auf verschiedenen
Zweigen (= Branches) voranzutreiben bzw. Tags oder Labels vom Code zu erstellen. Was
das genau ist und wie man damit umgeht, wird in Teil&amp;nbsp;3 dieser Serie besprochen.
&lt;/p&gt;
&lt;p&gt;
SCC-Systeme werden meist mit Diff- und Merging-Tools ergänzt, da dies natürlich Funktionalitäten
sind, die sich bei der täglichen Arbeit mit einer SCC notwendigerweise ergeben.
&lt;/p&gt;
&lt;p&gt;
Die Wahl der SCC ist auch hier eher unbedeutend und sollte halt einfach die jeweiligen
Bedürfnisse und Vorlieben abdecken.
&lt;/p&gt;
&lt;p&gt;
Auch hier, einige Vertreter dieser Kategorie: CVS, Subversion, Visual SourceSafe,
Sourcegear Vault
&lt;/p&gt;
&lt;p&gt;
In der Serie wird Subversion eingesetzt.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;h3&gt;Build-Script
&lt;/h3&gt;
&lt;p&gt;
&lt;em&gt;Build automation is the act of scripting or automating the process of compiling
computer source code into binary code. This automated build is in contrast to a manual
build process where a person has to perform multiple, often tedious and error prone
tasks.&lt;/em&gt; (&lt;a href="http://en.wikipedia.org/wiki/Build_Automation" target="_blank"&gt;Wikipedia&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
Ein Build-Script ist keine eigentliche Software-Komponente, sondern halt nur ein Script.
Was das Script dann schlussendlich tun soll, ist abhängig von den Wünschen und Anforderungen
der Projektteilnehmer. Was es aber grundsätzlich natürlich immer kann bzw. können
sollte, ist das schlichte kompilieren des Codes. Als erweiterte Möglichkeiten wären
zum Beispiel folgende Punkte denkbar:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Erstellung der Datenbank 
&lt;li&gt;
IIS Automatisierung (virt. Directories erstellen, Konfigurationen vornehmen etc.) 
&lt;li&gt;
Umgebungsabhängige Konfigurations-Dateien erstellen (Stichwort: ConnectionString) 
&lt;li&gt;
Automatisierte Test-Durchführung (z.B. UnitTests) 
&lt;li&gt;
SCC-Operationen 
&lt;li&gt;
und und und...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Seit .NET 2.0 haben .NET Entwickler die grosse Erleichterung, dass jedes Solution-
bzw. Projektfile von Visual Studio 2005 selbst bereits ein MSBuild-Skript darstellt,
welches zumindest mal die&amp;nbsp;Solution oder das Projekt durch einen simplen Kommandozeilen-Aufruf
von "&lt;strong&gt;msbuild mysolution.sln&lt;/strong&gt;" kompilieren kann. Damit ist bereits
die wichtigste Funktion eines BuildScripts abgedeckt, mit der auch schon einiges erreicht
werden kann (z.B. automatische Kompilierung über Scheduled Tasks).
&lt;/p&gt;
&lt;p&gt;
Vertreter dieser Kategorie sind zum Beispiel das eben genannte MSBuild, (n)ant oder
auch die klassischen make-Files.
&lt;/p&gt;
&lt;p&gt;
In dieser Serie werden wir auf MSBuild setzen.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;h3&gt;Build-Server / Continuous Integration Server
&lt;/h3&gt;
&lt;p&gt;
"&lt;em&gt;Continuous integration is the name that emerged in the Extreme Programming community
for the software engineering practice of immediately committing every change, no matter
how small, to a revision control system. Other developers should always work with
the latest version of the codebase.&lt;/em&gt;" (&lt;a href="http://en.wikipedia.org/wiki/Continuous_integration" target="_blank"&gt;Wikipedia&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
Build-Server im eigentlichen Sinne sind eigentlich heutzutage recht out.In aller Munde
hingegen ist Continuous Integration oder kurz CI. Wo genau die Unterschiede sind,
wird im entsprechenden Artikel behandelt - wobei der Schwerpunkt klar auf CI-Servern
gelegt wird.
&lt;/p&gt;
&lt;p&gt;
Vertreter dieser Kategorie sind Cruise Control (.NET), Team Foundation Server, TeamCity,
Bamboo
&lt;/p&gt;
&lt;p&gt;
Wir werden uns mit Cruise Control .NET beschäftigen.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Dies war mal so ein kleiner Überblick über die Themen dieser Serie. Jeder der folgenden
Artikel wird dann ein einzelnes dieser Themengebiete genauer beleuchten. 
&lt;/p&gt;
&lt;p&gt;
Um nochmals auf die eingangs erwähnten Fragestellungen zurückzukommen:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Geht es einfach darum dem Entwickler Freude zu bereiten, ihm ein "gutes Gefühl"
zu vermitteln? 
&lt;br&gt;
&lt;/strong&gt;Der Entwickler wird automatisch ein gutes Gefühl erhalten. Automatisch ausgeführte
Builds, Tests etc. werden ihm stets das Gefühl verleihen, dass das Programm auf gutem
Weg ist. Allein schon die morgendliche Nachricht, dass der Nightlybuild ohne Fehler
durchgelaufen ist, wirkt hier Wunder. Im Artikel über CI werden wir aber noch einiges
weiter gehen (Nightlybuilds != CI) 
&lt;li&gt;
&lt;strong&gt;Dem Projektleiter und Kunden ein Gefühl von Sicherheit zu vermitteln? 
&lt;br&gt;
&lt;/strong&gt;Durch den Einsatz von CI können wir ein stets lauffähiges System vorweisen
(das heisst nicht das alle Funktionen bereits vollständig implementiert sind etc.).
Es gibt doch nichts Schlimmeres, als wenn der Kunde etwas sehen möchte und der Entwickler
ihn mit lauter kryptischen (aber im Entwicklungsprozess) normalen Fehlermeldungen
konfrontiert. 
&lt;li&gt;
&lt;strong&gt;Oder einfach nur das Projekt rechtzeitig und gemäss Anforderungen&amp;nbsp;abzuschliessen? 
&lt;br&gt;
&lt;/strong&gt;Hierfür brauchts natürlich noch einiges mehr, als eine gute Infrastruktur
- aber ein erster Schritt ist damit getan.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Alle verwendeten Komponenten bis auf Visual Studio sind frei erhältlich, der Kostenpunkt
sollte also zumindest was die Lizenzkosten anbelangt keinen Grund darstellen, auf
diese wichtigen Komponenten zu verzichten - wie es mit dem Aufwand aussieht, werden
die nächsten Artikel zeigen.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=785ad017-1f7f-4502-8f22-8403ead4c574" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,785ad017-1f7f-4502-8f22-8403ead4c574.aspx</comments>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=26d130b4-4ed9-4e52-94b3-2dea7e10ac95</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,26d130b4-4ed9-4e52-94b3-2dea7e10ac95.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,26d130b4-4ed9-4e52-94b3-2dea7e10ac95.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=26d130b4-4ed9-4e52-94b3-2dea7e10ac95</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Ist zwar mittlerweile auch schon wieder ein paar Wochen her, aber es sei trotzdem
erwähnt: Auch das zweite und letzte Vordiplom sitzt nun fest in meiner Tasche! Neben
dem neu errungenen Zettel hat das vorallem auch die Konsequenz, dass das Grundstudium
nun abgeschlossen ist, Adieu Mathe, Physik &amp; Co. Dafür darf ich mich jetzt im
ersten Semester des Fachstudiums mit folgendem befassen:
</p>
        <ul>
          <li>
Systemsoftware (Systemnahe Entwicklung mit C, insbesondere Multithreading-Applikationen
mit Pthreads) 
</li>
          <li>
Datenbanksysteme 
</li>
          <li>
Data Mining 
</li>
          <li>
Paralleles Rechnen</li>
        </ul>
        <p>
Vielleicht findet ja das eine oder andere Thema auch noch in dieses Blog.
</p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=26d130b4-4ed9-4e52-94b3-2dea7e10ac95" />
      </body>
      <title>Geschafft die zweite</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,26d130b4-4ed9-4e52-94b3-2dea7e10ac95.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/09/19/GeschafftDieZweite.aspx</link>
      <pubDate>Wed, 19 Sep 2007 17:59:43 GMT</pubDate>
      <description>&lt;p&gt;
Ist zwar mittlerweile auch schon wieder ein paar Wochen her, aber es sei trotzdem
erwähnt: Auch das zweite und letzte Vordiplom sitzt nun fest in meiner Tasche! Neben
dem neu errungenen Zettel hat das vorallem auch die Konsequenz, dass das Grundstudium
nun abgeschlossen ist, Adieu Mathe, Physik &amp;amp; Co. Dafür darf ich mich jetzt im
ersten Semester des Fachstudiums mit folgendem befassen:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Systemsoftware (Systemnahe Entwicklung mit C, insbesondere Multithreading-Applikationen
mit Pthreads) 
&lt;li&gt;
Datenbanksysteme 
&lt;li&gt;
Data Mining 
&lt;li&gt;
Paralleles Rechnen&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Vielleicht findet ja das eine oder andere Thema auch noch in dieses Blog.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=26d130b4-4ed9-4e52-94b3-2dea7e10ac95" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,26d130b4-4ed9-4e52-94b3-2dea7e10ac95.aspx</comments>
      <category>About</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=57ed199e-3f8c-4539-bacd-5d592b6181fe</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,57ed199e-3f8c-4539-bacd-5d592b6181fe.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,57ed199e-3f8c-4539-bacd-5d592b6181fe.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=57ed199e-3f8c-4539-bacd-5d592b6181fe</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.rauchy.net/regionerate/" target="_blank">Regionerate</a> ist
ein interessantes kleines Tool mit dem man C#-Code per Mausklick nach einem definierten
Template umformatieren kann (zB. Fields, Properties, Methoden etc. in Regions
trennen). So kann man sicherstellen, dass der Code immer gleich formatiert ist.
</p>
        <p>
Dieser <a href="http://www.rauchy.net/regionerate/2007/06/regionerate-101.html" target="_blank">Screencast</a> gibt
einen guten Einblick in die Funktionen des Tools.
</p>
        <p>
Das ganze funktioniert in VS 2005, Orcas und SharpDevelop. 
</p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=57ed199e-3f8c-4539-bacd-5d592b6181fe" />
      </body>
      <title>Regionerate</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,57ed199e-3f8c-4539-bacd-5d592b6181fe.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/06/27/Regionerate.aspx</link>
      <pubDate>Wed, 27 Jun 2007 19:00:45 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.rauchy.net/regionerate/" target="_blank"&gt;Regionerate&lt;/a&gt;&amp;nbsp;ist
ein interessantes kleines Tool mit dem man C#-Code per Mausklick nach einem definierten
Template umformatieren kann (zB.&amp;nbsp;Fields, Properties, Methoden etc. in Regions
trennen). So kann man sicherstellen, dass der&amp;nbsp;Code immer gleich formatiert ist.
&lt;/p&gt;
&lt;p&gt;
Dieser &lt;a href="http://www.rauchy.net/regionerate/2007/06/regionerate-101.html" target="_blank"&gt;Screencast&lt;/a&gt; gibt
einen guten Einblick in die Funktionen des Tools.
&lt;/p&gt;
&lt;p&gt;
Das ganze funktioniert in VS 2005, Orcas und SharpDevelop.&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=57ed199e-3f8c-4539-bacd-5d592b6181fe" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,57ed199e-3f8c-4539-bacd-5d592b6181fe.aspx</comments>
      <category>C#</category>
      <category>Software</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=aca2b6bd-b3a1-43af-871e-57fb5914b0e1</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,aca2b6bd-b3a1-43af-871e-57fb5914b0e1.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,aca2b6bd-b3a1-43af-871e-57fb5914b0e1.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=aca2b6bd-b3a1-43af-871e-57fb5914b0e1</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://codebetter.com/blogs/scott.bellware/default.aspx" target="_blank">Scott
Bellware</a>, seines Zeichens (verdienter) C#-MVP, hat einen sehr interessanten <a href="http://codebetter.com/blogs/scott.bellware/archive/2007/06/26/164729.aspx" target="_blank">Artikel</a> über
die Handhabung von Objekt-Referenzen geschrieben. Er geht kurz aber verständlich auf
die möglichen Formen und deren Risiken ein, und zeigt wie man mit Hilfe eines Dependency
Injection Frameworks wie <a href="http://www.springframework.net/" target="_blank">Spring.NET</a> seine
Abhängigkeiten "lockern" kann und den Code somit testbarer zu machen. Sehr empfehlenswert!
</p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=aca2b6bd-b3a1-43af-871e-57fb5914b0e1" />
      </body>
      <title>Dependency Patterns</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,aca2b6bd-b3a1-43af-871e-57fb5914b0e1.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/06/27/DependencyPatterns.aspx</link>
      <pubDate>Wed, 27 Jun 2007 18:54:01 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://codebetter.com/blogs/scott.bellware/default.aspx" target="_blank"&gt;Scott
Bellware&lt;/a&gt;, seines Zeichens (verdienter) C#-MVP, hat einen sehr interessanten &lt;a href="http://codebetter.com/blogs/scott.bellware/archive/2007/06/26/164729.aspx" target="_blank"&gt;Artikel&lt;/a&gt; über
die Handhabung von Objekt-Referenzen geschrieben. Er geht kurz aber verständlich auf
die möglichen Formen und deren Risiken ein, und zeigt wie man mit Hilfe eines Dependency
Injection&amp;nbsp;Frameworks wie &lt;a href="http://www.springframework.net/" target="_blank"&gt;Spring.NET&lt;/a&gt; seine
Abhängigkeiten "lockern" kann und den Code somit&amp;nbsp;testbarer zu machen. Sehr empfehlenswert!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=aca2b6bd-b3a1-43af-871e-57fb5914b0e1" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,aca2b6bd-b3a1-43af-871e-57fb5914b0e1.aspx</comments>
      <category>C#</category>
      <category>Patterns</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=b02c5f29-14fe-41b9-8c5e-43a2d7f8b065</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,b02c5f29-14fe-41b9-8c5e-43a2d7f8b065.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,b02c5f29-14fe-41b9-8c5e-43a2d7f8b065.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=b02c5f29-14fe-41b9-8c5e-43a2d7f8b065</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Mit iTextSharp lassen sich einigermassen komfortabel mehrere PDF-Dateien in eine einzige
mergen.
</p>
        <p>
Folgendes Skript zeigt wies geht:
</p>
        <p>
 
</p>
        <pre class="code">
          <span style="color: rgb(0, 0, 255);">using</span> System; <span style="color: rgb(0, 0, 255);">using</span> System.IO; <span style="color: rgb(0, 0, 255);">using</span> iTextSharp.text; <span style="color: rgb(0, 0, 255);">using</span> iTextSharp.text.pdf; <span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(43, 145, 175);">PdfMerge </span>{ <span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 255);">void</span> MergeFiles(<span style="color: rgb(0, 0, 255);">string</span> destinationFile, <span style="color: rgb(0, 0, 255);">string</span>[]
sourceFiles) { <span style="color: rgb(0, 0, 255);">try </span> { <span style="color: rgb(0, 0, 255);">int</span> f
= 0; PdfReader reader = <span style="color: rgb(0, 0, 255);">new</span> PdfReader(sourceFiles[f]); <span style="color: rgb(0, 0, 255);">int</span> n
= reader.NumberOfPages; Document document = <span style="color: rgb(0, 0, 255);">new</span> Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(document, <span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(43, 145, 175);">FileStream</span>(destinationFile, <span style="color: rgb(43, 145, 175);">FileMode</span>.Create));
document.Open(); PdfContentByte cb = writer.DirectContent; PdfImportedPage page; <span style="color: rgb(0, 0, 255);">int</span> rotation; <span style="color: rgb(0, 0, 255);">while</span> (f
&lt; sourceFiles.Length) { <span style="color: rgb(0, 0, 255);">int</span> i = 0; <span style="color: rgb(0, 0, 255);">while</span> (i
&lt; n) { i++; document.SetPageSize(reader.GetPageSizeWithRotation(i)); document.NewPage();
page = writer.GetImportedPage(reader, i); rotation = reader.GetPageRotation(i); <span style="color: rgb(0, 0, 255);">if</span> (rotation
== 90 || rotation == 270) cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height); <span style="color: rgb(0, 0, 255);">else </span> cb.AddTemplate(page,
1f, 0, 0, 1f, 0, 0); } f++; <span style="color: rgb(0, 0, 255);">if</span> (f &lt;
sourceFiles.Length) { reader = <span style="color: rgb(0, 0, 255);">new</span> PdfReader(sourceFiles[f]);
n = reader.NumberOfPages; } } document.Close(); } <span style="color: rgb(0, 0, 255);">catch</span> (<span style="color: rgb(43, 145, 175);">Exception</span> ex)
{ <span style="color: rgb(43, 145, 175);">Console</span>.Error.WriteLine(ex.Message);
} } }</pre>
        <a href="http://11011.net/software/vspaste">
        </a>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=b02c5f29-14fe-41b9-8c5e-43a2d7f8b065" />
      </body>
      <title>PDF-Dateien mergen</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,b02c5f29-14fe-41b9-8c5e-43a2d7f8b065.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/06/27/PDFDateienMergen.aspx</link>
      <pubDate>Wed, 27 Jun 2007 18:34:37 GMT</pubDate>
      <description>&lt;p&gt;
Mit iTextSharp lassen sich einigermassen komfortabel mehrere PDF-Dateien in eine einzige
mergen.
&lt;/p&gt;
&lt;p&gt;
Folgendes Skript zeigt wies geht:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.IO; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; iTextSharp.text; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; iTextSharp.text.pdf; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;PdfMerge &lt;/span&gt;{ &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; MergeFiles(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; destinationFile, &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;[]
sourceFiles) { &lt;span style="color: rgb(0, 0, 255);"&gt;try &lt;/span&gt; { &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; f
= 0; PdfReader reader = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; PdfReader(sourceFiles[f]); &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; n
= reader.NumberOfPages; Document document = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(document, &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;FileStream&lt;/span&gt;(destinationFile, &lt;span style="color: rgb(43, 145, 175);"&gt;FileMode&lt;/span&gt;.Create));
document.Open(); PdfContentByte cb = writer.DirectContent; PdfImportedPage page; &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; rotation; &lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt; (f
&amp;lt; sourceFiles.Length) { &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; i = 0; &lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt; (i
&amp;lt; n) { i++; document.SetPageSize(reader.GetPageSizeWithRotation(i)); document.NewPage();
page = writer.GetImportedPage(reader, i); rotation = reader.GetPageRotation(i); &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (rotation
== 90 || rotation == 270) cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height); &lt;span style="color: rgb(0, 0, 255);"&gt;else &lt;/span&gt; cb.AddTemplate(page,
1f, 0, 0, 1f, 0, 0); } f++; &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (f &amp;lt;
sourceFiles.Length) { reader = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; PdfReader(sourceFiles[f]);
n = reader.NumberOfPages; } } document.Close(); } &lt;span style="color: rgb(0, 0, 255);"&gt;catch&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;Exception&lt;/span&gt; ex)
{ &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.Error.WriteLine(ex.Message);
} } }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=b02c5f29-14fe-41b9-8c5e-43a2d7f8b065" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,b02c5f29-14fe-41b9-8c5e-43a2d7f8b065.aspx</comments>
      <category>.NET divers</category>
      <category>C#</category>
      <category>Komponenten</category>
      <category>Snippets</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=faf67bb7-a384-499d-84a5-2d1ab61629fd</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,faf67bb7-a384-499d-84a5-2d1ab61629fd.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,faf67bb7-a384-499d-84a5-2d1ab61629fd.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=faf67bb7-a384-499d-84a5-2d1ab61629fd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Um Word-Dateien programmatisch in PDF's zu wandeln, gibts einige kommerzielle Lösungen.
Eine günstigere, nämlich kostenlose Alternative bietet das Tool <a href="http://www.pdfforge.org" target="_blank">PDFCreator</a>.
</p>
        <p>
          <a href="http://www.pdfforge.org" target="_blank">PDFCreator</a> nistet sich als Druckertreiber
in Windows ein und erlaubt so die PDF-Konvertierung verschiedenster Datentypen. Das
beste daran: PDFCreator bietet in den neueren Versionen auch eine COM-Schnittstelle,
womit das Tool auch elegant aus dem eigenen Code angesprochen werden kann.
</p>
        <p>
Im <a href="http://www.pdfforge.org/products/pdfcreator/download" target="_blank">Download
von PDFCreator</a> sind zwei Samples zur Nutzung des COM-Interfaces mit .NET (1.1
und 2.0) vorhanden. Sei noch zu erwähnen, dass es bei mir nur mit dem GPL-Download
funktioniert hat.
</p>
        <p>
Einziger Nachteil ist natürlich, dass für diesen Vorgang Word installiert sein muss.
</p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=faf67bb7-a384-499d-84a5-2d1ab61629fd" />
      </body>
      <title>Word-Dateien zu PDF konvertieren</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,faf67bb7-a384-499d-84a5-2d1ab61629fd.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/06/27/WordDateienZuPDFKonvertieren.aspx</link>
      <pubDate>Wed, 27 Jun 2007 16:29:49 GMT</pubDate>
      <description>&lt;p&gt;
Um Word-Dateien programmatisch in PDF's zu wandeln, gibts einige kommerzielle Lösungen.
Eine günstigere, nämlich kostenlose Alternative bietet das Tool &lt;a href="http://www.pdfforge.org" target="_blank"&gt;PDFCreator&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.pdfforge.org" target="_blank"&gt;PDFCreator&lt;/a&gt; nistet sich als Druckertreiber
in Windows ein und erlaubt so die PDF-Konvertierung verschiedenster Datentypen. Das
beste daran: PDFCreator bietet in den neueren Versionen auch eine COM-Schnittstelle,
womit das Tool auch elegant aus dem eigenen Code angesprochen werden kann.
&lt;/p&gt;
&lt;p&gt;
Im &lt;a href="http://www.pdfforge.org/products/pdfcreator/download" target="_blank"&gt;Download
von PDFCreator&lt;/a&gt; sind zwei Samples zur Nutzung des COM-Interfaces mit .NET (1.1
und 2.0)&amp;nbsp;vorhanden. Sei noch zu erwähnen, dass es bei mir nur mit dem GPL-Download
funktioniert hat.
&lt;/p&gt;
&lt;p&gt;
Einziger Nachteil ist natürlich, dass für diesen Vorgang Word installiert sein muss.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=faf67bb7-a384-499d-84a5-2d1ab61629fd" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,faf67bb7-a384-499d-84a5-2d1ab61629fd.aspx</comments>
      <category>.NET divers</category>
      <category>Software</category>
      <category>Komponenten</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=654f7f42-9c31-4c66-b254-51df1a9579b5</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,654f7f42-9c31-4c66-b254-51df1a9579b5.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,654f7f42-9c31-4c66-b254-51df1a9579b5.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=654f7f42-9c31-4c66-b254-51df1a9579b5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Von meinem absoluten Liebling in Sachen "mach mehr aus VS" ist nun die Version 3 erschienen.
</p>
        <p>
Neben dem, dass auch in der dritten Version meine zwei Cores mitsamt RAM arg
gekitzelt werden, sind noch einige <a href="http://www.jetbrains.com/resharper/" target="_blank">weitere
nette Features</a> dazugekommen.
</p>
        <p>
Eine uneingeschränkte 30-tägige Testversion gibts <a href="http://www.jetbrains.com/resharper/download/index.html" target="_blank">hier</a>.
</p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=654f7f42-9c31-4c66-b254-51df1a9579b5" />
      </body>
      <title>ReSharper 3.0 ist da!</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,654f7f42-9c31-4c66-b254-51df1a9579b5.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/06/21/ReSharper30IstDa.aspx</link>
      <pubDate>Thu, 21 Jun 2007 17:10:14 GMT</pubDate>
      <description>&lt;p&gt;
Von meinem absoluten Liebling in Sachen "mach mehr aus VS" ist nun die Version 3 erschienen.
&lt;/p&gt;
&lt;p&gt;
Neben dem, dass auch in der dritten Version meine zwei Cores&amp;nbsp;mitsamt RAM arg
gekitzelt werden, sind noch einige &lt;a href="http://www.jetbrains.com/resharper/" target="_blank"&gt;weitere
nette Features&lt;/a&gt; dazugekommen.
&lt;/p&gt;
&lt;p&gt;
Eine uneingeschränkte 30-tägige Testversion gibts &lt;a href="http://www.jetbrains.com/resharper/download/index.html" target="_blank"&gt;hier&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=654f7f42-9c31-4c66-b254-51df1a9579b5" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,654f7f42-9c31-4c66-b254-51df1a9579b5.aspx</comments>
      <category>Software</category>
      <category>VS 2005</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=cc53be2f-4f0b-4a08-b64c-0776c645d004</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,cc53be2f-4f0b-4a08-b64c-0776c645d004.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,cc53be2f-4f0b-4a08-b64c-0776c645d004.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=cc53be2f-4f0b-4a08-b64c-0776c645d004</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <a href="http://blog.nettigkeiten.ch/PermaLink,guid,023454fd-b5a0-477c-9747-382a0c5ecf92.aspx">Hier</a> habe
ich über eine Exposé-Variante für Windows Vista geschrieben.<br />
Nun ist mir noch eine Adaption des bekannten Dock aus OS X (wie heisst das Dingens
eigentlich) untergekommen.<br /><br /><a href="http://www.punksoftware.com/rocketdock">RocketDock</a>, so nennt sich das,
ist ebenfalls Freeware und funktioniert sehr gut! 
<br /><br />
Hier das ganze in Action:<br /><br /><script src="http://flash.revver.com/player/1.0/player.js?mediaId:160224;affiliateId:0;height:392;width:480;" type="text/javascript"></script><img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=cc53be2f-4f0b-4a08-b64c-0776c645d004" /></body>
      <title>RocketDock für Vista</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,cc53be2f-4f0b-4a08-b64c-0776c645d004.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/05/29/RocketDockF%c3%bcrVista.aspx</link>
      <pubDate>Tue, 29 May 2007 15:04:38 GMT</pubDate>
      <description>&lt;a href="http://blog.nettigkeiten.ch/PermaLink,guid,023454fd-b5a0-477c-9747-382a0c5ecf92.aspx"&gt;Hier&lt;/a&gt; habe
ich über eine Exposé-Variante für Windows Vista geschrieben.&lt;br&gt;
Nun ist mir noch eine Adaption des bekannten Dock aus OS X (wie heisst das Dingens
eigentlich) untergekommen.&lt;br&gt;
&lt;br&gt;
&lt;a href="http://www.punksoftware.com/rocketdock"&gt;RocketDock&lt;/a&gt;, so nennt sich das,
ist ebenfalls Freeware und funktioniert sehr gut! 
&lt;br&gt;
&lt;br&gt;
Hier das ganze in Action:&lt;br&gt;
&lt;br&gt;
&lt;script src="http://flash.revver.com/player/1.0/player.js?mediaId:160224;affiliateId:0;height:392;width:480;" type="text/javascript"&gt;&lt;/script&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=cc53be2f-4f0b-4a08-b64c-0776c645d004" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,cc53be2f-4f0b-4a08-b64c-0776c645d004.aspx</comments>
      <category>Software</category>
    </item>
    <item>
      <trackback:ping>http://blog.nettigkeiten.ch/Trackback.aspx?guid=03724581-3463-43a8-bd99-d724bfe05fcb</trackback:ping>
      <pingback:server>http://blog.nettigkeiten.ch/pingback.aspx</pingback:server>
      <pingback:target>http://blog.nettigkeiten.ch/PermaLink,guid,03724581-3463-43a8-bd99-d724bfe05fcb.aspx</pingback:target>
      <dc:creator>Dani Meier</dc:creator>
      <wfw:comment>http://blog.nettigkeiten.ch/CommentView,guid,03724581-3463-43a8-bd99-d724bfe05fcb.aspx</wfw:comment>
      <wfw:commentRss>http://blog.nettigkeiten.ch/SyndicationService.asmx/GetEntryCommentsRss?guid=03724581-3463-43a8-bd99-d724bfe05fcb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Enums sind ein einfacher und komfortabler Weg um z. B. Status- oder Modus-Indikatoren
zu speichern.<br />
Jeder Entwickler braucht dieses Feature wohl tagtäglich, sei es über "built-in" Enumerationen
wie System.IO.FileAccess oder über eigens definierte.
</p>
        <h4>
          <strong>Basics</strong>
        </h4>
        <p>
Hier als einfaches Beispiel ein Enum, das die Benutzungsart einer Software beschreibt:
</p>
        <blockquote>
          <pre class="code">
            <span style="color: rgb(0, 0, 255);">public</span>
            <span style="color: rgb(0, 0, 255);">enum</span>
            <span style="color: rgb(43, 145, 175);">UsageMode </span>{
Private, Commercial, Education }</pre>
        </blockquote>
        <p>
und deren Verwendung in einer Klasse "Software":
</p>
        <blockquote>
          <pre class="code">
            <span style="color: rgb(0, 0, 255);">public</span>
            <span style="color: rgb(0, 0, 255);">class</span>
            <span style="color: rgb(43, 145, 175);">Software </span>{ <span style="color: rgb(43, 145, 175);">UsageMode</span> usage
= <span style="color: rgb(43, 145, 175);">UsageMode</span>.Commercial; <span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(43, 145, 175);">UsageMode</span> Usage
{ <span style="color: rgb(0, 0, 255);">get</span> { <span style="color: rgb(0, 0, 255);">return</span> usage;
} <span style="color: rgb(0, 0, 255);">set</span> { usage = <span style="color: rgb(0, 0, 255);">value</span>;
} } }</pre>
        </blockquote>
        <p>
Enums sind im Prinzip nichts anderes, als benannte Konstanten für Integer-Werte. Im
Beispiel werden die Werte wie folgt implizit durchnummeriert.
</p>
        <blockquote>
          <pre class="code">
            <span style="color: rgb(0, 0, 255);">public</span>
            <span style="color: rgb(0, 0, 255);">enum</span>
            <span style="color: rgb(43, 145, 175);">UsageMode </span>{
Private = 0, Commercial = 1, Education = 2 }</pre>
        </blockquote>
        <p>
Dies lässt sich durch die schlichte Zuweisung eines beliebigen Integers aber ändern.
</p>
        <p>
Dadurch, dass Enums neben benannten Konstanten eben auch numerische Werte darstellen,
eignen sie sich auch sehr gut, um auf Arrays zu mappen.
</p>
        <blockquote>
          <p>
            <span style="color: rgb(0, 0, 255);">
            </span>
          </p>
          <pre class="code">
            <span style="color: rgb(0, 0, 255);">public</span>
            <span style="color: rgb(0, 0, 255);">class</span>
            <span style="color: rgb(43, 145, 175);">Software </span>{ <span style="color: rgb(43, 145, 175);">UsageMode</span> usage
= <span style="color: rgb(43, 145, 175);">UsageMode</span>.Commercial; <span style="color: rgb(0, 0, 255);">string</span>[]
humanText = <span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 255);">string</span>[]
{ <span style="color: rgb(163, 21, 21);">"Private (non-commercial) usage"</span>, <span style="color: rgb(163, 21, 21);">"Unlimited
commercial usage"</span>, <span style="color: rgb(163, 21, 21);">"Educational usage" </span> }; <span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(43, 145, 175);">UsageMode</span> Usage
{ <span style="color: rgb(0, 0, 255);">get</span> { <span style="color: rgb(0, 0, 255);">return</span> usage;
} <span style="color: rgb(0, 0, 255);">set</span> { usage = <span style="color: rgb(0, 0, 255);">value</span>;
} } <span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 255);">string</span> HumanText
{ <span style="color: rgb(0, 0, 255);">get</span> { <span style="color: rgb(0, 0, 255);">return</span> humanText[(<span style="color: rgb(0, 0, 255);">int</span>)usage];
} } }</pre>
          <a href="http://11011.net/software/vspaste">
          </a>
        </blockquote>
        <p>
Hier wird also eine Enumeration benutzt, um einen strukturierten Zugriff auf das String-Array
humanText zu ermöglichen.
</p>
        <h4>
          <strong>Wenns mal etwas mehr sein soll</strong>
        </h4>
        <p>
Was nun aber, wenn ein Int32 für die gewünschten Datentypen nicht mehr ausreicht?
Kein Problem, der zugrundeliegende Typ einer Enum kann über Vererbung geändert werden.
So lässt sich eine Enum problemlos mit einem Int64 (long) verwenden:
</p>
        <blockquote>
          <pre class="code">
            <span style="color: rgb(0, 0, 255);">public</span>
            <span style="color: rgb(0, 0, 255);">enum</span>
            <span style="color: rgb(43, 145, 175);">UsageMode</span> : <span style="color: rgb(0, 0, 255);">long </span>{
Private = 2147483640L, Commercial = 2147483641L, Education = 2147483642L }</pre>
        </blockquote>
        <p>
Es liegt auf der Hand, dass dies nur in sehr speziellen Fällen notwendig ist - kann
aber trotzdem sehr nützlich sein, wenn es zum Beispiel darum geht, Zahlen &gt; 2^31
über benannnte Konstanten zugänglich zu machen.
</p>
        <h4>
          <strong>Bit-Flags</strong>
        </h4>
        <p>
Bis jetzt sind wir immer davon ausgegangen, dass sich die einzelnen Enumerationswerte
ausschliessen. Nicht selten jedoch, sollen sich die Werte auch kombinieren lassen.
So ist es durchaus vorstellbar, dass eine Software zu privaten wie auch kommerziellen
Zwecken eingesetzt wird.
</p>
        <p>
Dies lässt sich erreichen, indem man für die einzelne Werte auschliesslich Potenzen
von 2 verwendet:
</p>
        <blockquote>
          <pre class="code">
            <span style="color: rgb(0, 0, 255);">public</span>
            <span style="color: rgb(0, 0, 255);">enum</span>
            <span style="color: rgb(43, 145, 175);">UsageMode </span>{
Private = 1, <span style="color: rgb(0, 128, 0);">// 2^0 </span> Commercial = 2, <span style="color: rgb(0, 128, 0);">//
2^1 </span> Education = 4 <span style="color: rgb(0, 128, 0);">// 2^2 </span>}</pre>
        </blockquote>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
Nun, wieso denn das? Wenn man sich dann die Verwendung anschaut, wird auch das klar:
</p>
        <blockquote>
          <pre class="code">usage = <span style="color: rgb(43, 145, 175);">UsageMode</span>.Commercial
| <span style="color: rgb(43, 145, 175);">UsageMode</span>.Private;</pre>
        </blockquote>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
Die beiden Werte werden also mit einem | (OR) verbunden. Wenn man dies nun auf die
Zahlenwerte überträgt
</p>
        <blockquote>
          <p>
1 OR 2 = 3
</p>
        </blockquote>
        <p>
sieht man, dass die Kombination einen Zahlenwert ergibt, die in der Enum nicht vorkommt
und eindeutig diesem Paar zugewiesen werden kann.
</p>
        <p>
Und das ist natürlich notwendig, da man ja den Wert der Enum auch abfragen will:
</p>
        <blockquote>
          <pre class="code">
            <span style="color: rgb(0, 0, 255);">bool</span> isPrivateUsage
= (<span style="color: rgb(43, 145, 175);">UsageMode</span>.Private &amp; usage) == <span style="color: rgb(43, 145, 175);">UsageMode</span>.Private;</pre>
        </blockquote>
        <p>
Man ANDet also den aktuellen Wert (usage) mit dem zu prüfenden Wert (UsageMode.Private).
Oder in Zahlen ausgedrückt:
</p>
        <blockquote>
          <p>
1 AND 3 = 1
</p>
        </blockquote>
        <p>
Nun liegt es natürlich nahe, dass man für die 3 hier auch einen Enum-Wert einführen
könnte, zum Beispiel "PrivateAndCommercial", dies würde die Benützung vereinfachen,
da zur Abfrage bzw. Aktivierung nicht jedes mal mit Bit-Operatoren hantiert werden
müsste. Solche Kombinationen sollte man einführen, sofern sie gebräuchlich sind.
</p>
        <p>
Oftmals wird auch ein Wert benötigt, der indiziert, dass keiner der Werte aktiviert
wurde. Dieser (und nur dieser!) sollte dann jeweils mit der Zahl 0 versehen werden.
</p>
        <blockquote>
          <pre class="code">
            <span style="color: rgb(0, 0, 255);">
            </span>
          </pre>
          <pre class="code">[System.<span style="color: rgb(43, 145, 175);">Flags</span>()] <span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 255);">enum</span><span style="color: rgb(43, 145, 175);">UsageMode </span>{
None = 0, Private = 1, Commercial = 2, PrivateAndCommercial = 3, Education = 4 }</pre>
        </blockquote>
        <h4>
          <strong>System.Flags-Attribut</strong>
        </h4>
        <p>
Hier wurde nun noch das System.Flags-Attribut eingeführt. Dieses ist zwar nicht unbedingt
notwendig für dieses Verhalten, ist jedoch empfehlenswert. Einfluss hat das Attribut
zum Beispiel auf die Ausgabe des Enum-Wertes über die ToString()-Methode:
</p>
        <blockquote>
          <pre class="code">usage = <span style="color: rgb(43, 145, 175);">UsageMode</span>.Private
| <span style="color: rgb(43, 145, 175);">UsageMode</span>.Commercial; <span style="color: rgb(43, 145, 175);">Console</span>.WriteLine(usage.ToString()); 
<br /><span style="color: rgb(0, 128, 0);">// Ausgabe mit Flags: PrivateAndCommercial; Ausgabe
ohne Flags: PrivateAndCommercial </span>usage = <span style="color: rgb(43, 145, 175);">UsageMode</span>.Private
| <span style="color: rgb(43, 145, 175);">UsageMode</span>.Education; <span style="color: rgb(43, 145, 175);">Console</span>.WriteLine(usage.ToString()); 
<br /><span style="color: rgb(0, 128, 0);">// Ausgabe mit Flags: Private, Commercial; Ausgabe
ohne Flags: 3</span></pre>
        </blockquote>
        <p>
Die kombinierten Werte werden also bei gesetztem Flags-Attribut mit Kommata getrennt, statt
einfach als Zahl, ausgegeben. Dies kann sehr nützlich sein. So kann man zum Beispiel
über die Split-Funktion von String so die einzelnen Werte sehr einfach in ein Array
überführen.
</p>
        <h4>
          <strong>Fazit</strong>
        </h4>
        <p>
Enums bieten also ein sehr einfaches und flexibles Werkzeug, um mit Konstanten Werten
zu hantieren. Gerade Anfänger lassen sich zu gerne von der Flags-Funktion abschrecken,
da sie so sehr nach "Bits rumschieben" schmeckt. Die Beispiele zeigen jedoch, dass
die Anwendung denkbar einfach und dafür umso Leistungsfähiger ist.
</p>
        <p>
Hier noch zwei interessante Links in diesem Zusammenhang:<br /><a title="Enum Design-Guidelines von Krzysztof Cwalina" href="http://blogs.msdn.com/kcwalina/archive/2004/05/18/134208.aspx" target="_blank">Enum
Design-Guidelines von Krzysztof Cwalina</a><br /><a title="MSDN (C#)" href="http://msdn2.microsoft.com/en-us/library/sbbt4032%28VS.80%29.aspx" target="_blank">MSDN
(C#)</a></p>
        <img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=03724581-3463-43a8-bd99-d724bfe05fcb" />
      </body>
      <title>Enums</title>
      <guid isPermaLink="false">http://blog.nettigkeiten.ch/PermaLink,guid,03724581-3463-43a8-bd99-d724bfe05fcb.aspx</guid>
      <link>http://blog.nettigkeiten.ch/2007/05/29/Enums.aspx</link>
      <pubDate>Tue, 29 May 2007 14:47:36 GMT</pubDate>
      <description>&lt;p&gt;
Enums sind ein einfacher und komfortabler Weg um z. B. Status- oder Modus-Indikatoren
zu speichern.&lt;br&gt;
Jeder Entwickler braucht dieses Feature wohl tagtäglich, sei es über "built-in" Enumerationen
wie System.IO.FileAccess oder über eigens definierte.
&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Basics&lt;/strong&gt;
&lt;/h4&gt;
&lt;p&gt;
Hier als einfaches&amp;nbsp;Beispiel ein Enum, das die Benutzungsart einer Software beschreibt:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode &lt;/span&gt;{
Private, Commercial, Education }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
und deren Verwendung in einer Klasse "Software":
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Software &lt;/span&gt;{ &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt; usage
= &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Commercial; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt; Usage
{ &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; usage;
} &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt; { usage = &lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt;;
} } }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Enums sind im Prinzip nichts anderes, als benannte Konstanten für Integer-Werte. Im
Beispiel werden die Werte wie folgt implizit durchnummeriert.
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode &lt;/span&gt;{
Private = 0, Commercial = 1, Education = 2 }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Dies lässt sich durch die schlichte Zuweisung eines beliebigen Integers aber ändern.
&lt;/p&gt;
&lt;p&gt;
Dadurch, dass Enums neben benannten Konstanten eben auch numerische Werte darstellen,
eignen sie sich auch sehr gut, um auf Arrays zu mappen.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Software &lt;/span&gt;{ &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt; usage
= &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Commercial; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;[]
humanText = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;[]
{ &lt;span style="color: rgb(163, 21, 21);"&gt;"Private (non-commercial) usage"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"Unlimited
commercial usage"&lt;/span&gt;, &lt;span style="color: rgb(163, 21, 21);"&gt;"Educational usage" &lt;/span&gt; }; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt; Usage
{ &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; usage;
} &lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt; { usage = &lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt;;
} } &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; HumanText
{ &lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt; { &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; humanText[(&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;)usage];
} } }&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Hier wird also eine Enumeration benutzt, um einen strukturierten Zugriff auf das String-Array
humanText zu ermöglichen.
&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Wenns mal etwas mehr sein soll&lt;/strong&gt;
&lt;/h4&gt;
&lt;p&gt;
Was nun aber, wenn ein Int32 für die gewünschten Datentypen nicht mehr ausreicht?
Kein Problem, der zugrundeliegende Typ einer Enum kann über Vererbung geändert werden.
So lässt sich eine Enum problemlos mit einem Int64 (long) verwenden:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt; : &lt;span style="color: rgb(0, 0, 255);"&gt;long &lt;/span&gt;{
Private = 2147483640L, Commercial = 2147483641L, Education = 2147483642L }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Es liegt auf der Hand, dass dies nur in sehr speziellen Fällen notwendig ist - kann
aber trotzdem sehr nützlich sein, wenn es zum Beispiel darum geht, Zahlen &amp;gt; 2^31
über benannnte Konstanten zugänglich zu machen.
&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Bit-Flags&lt;/strong&gt;
&lt;/h4&gt;
&lt;p&gt;
Bis jetzt sind wir immer davon ausgegangen, dass sich die einzelnen Enumerationswerte
ausschliessen. Nicht selten jedoch, sollen sich die Werte auch kombinieren lassen.
So ist es durchaus vorstellbar, dass eine Software zu privaten wie auch kommerziellen
Zwecken eingesetzt wird.
&lt;/p&gt;
&lt;p&gt;
Dies lässt sich erreichen, indem man für die einzelne Werte auschliesslich Potenzen
von 2 verwendet:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode &lt;/span&gt;{
Private = 1, &lt;span style="color: rgb(0, 128, 0);"&gt;// 2^0 &lt;/span&gt; Commercial = 2, &lt;span style="color: rgb(0, 128, 0);"&gt;//
2^1 &lt;/span&gt; Education = 4 &lt;span style="color: rgb(0, 128, 0);"&gt;// 2^2 &lt;/span&gt;}&lt;/pre&gt;
&lt;/blockquote&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
Nun, wieso denn das? Wenn man sich dann die Verwendung anschaut, wird auch das klar:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;usage = &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Commercial
| &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Private;&lt;/pre&gt;
&lt;/blockquote&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
Die beiden Werte werden also mit einem | (OR) verbunden. Wenn man dies nun auf die
Zahlenwerte überträgt
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
1 OR 2 = 3
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
sieht man, dass die Kombination einen Zahlenwert ergibt, die in der Enum nicht vorkommt
und eindeutig diesem Paar zugewiesen werden kann.
&lt;/p&gt;
&lt;p&gt;
Und das ist natürlich notwendig, da man ja den Wert der Enum auch abfragen will:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; isPrivateUsage
= (&lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Private &amp;amp; usage) == &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Private;&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Man ANDet also den aktuellen Wert (usage) mit dem zu prüfenden Wert (UsageMode.Private).
Oder in Zahlen ausgedrückt:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
1 AND 3 = 1
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Nun liegt es natürlich nahe, dass man für die 3 hier auch einen Enum-Wert einführen
könnte, zum Beispiel "PrivateAndCommercial", dies würde die Benützung vereinfachen,
da zur Abfrage bzw. Aktivierung nicht jedes mal mit Bit-Operatoren hantiert werden
müsste. Solche Kombinationen sollte man einführen, sofern sie gebräuchlich sind.
&lt;/p&gt;
&lt;p&gt;
Oftmals wird auch ein Wert benötigt, der indiziert, dass keiner der Werte aktiviert
wurde. Dieser (und nur dieser!)&amp;nbsp;sollte dann jeweils mit der Zahl 0 versehen werden.
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="code"&gt;[System.&lt;span style="color: rgb(43, 145, 175);"&gt;Flags&lt;/span&gt;()] &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode &lt;/span&gt;{
None = 0, Private = 1, Commercial = 2, PrivateAndCommercial = 3, Education = 4 }&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;h4&gt;&lt;strong&gt;System.Flags-Attribut&lt;/strong&gt;
&lt;/h4&gt;
&lt;p&gt;
Hier wurde nun noch das System.Flags-Attribut eingeführt. Dieses ist zwar nicht unbedingt
notwendig für dieses Verhalten, ist jedoch empfehlenswert. Einfluss hat das Attribut
zum Beispiel auf die Ausgabe des Enum-Wertes über die ToString()-Methode:
&lt;/p&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;usage = &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Private
| &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Commercial; &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(usage.ToString()); 
&lt;br&gt;
&lt;span style="color: rgb(0, 128, 0);"&gt;// Ausgabe mit Flags: PrivateAndCommercial; Ausgabe
ohne Flags: PrivateAndCommercial &lt;/span&gt;usage = &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Private
| &lt;span style="color: rgb(43, 145, 175);"&gt;UsageMode&lt;/span&gt;.Education; &lt;span style="color: rgb(43, 145, 175);"&gt;Console&lt;/span&gt;.WriteLine(usage.ToString()); 
&lt;br&gt;
&lt;span style="color: rgb(0, 128, 0);"&gt;// Ausgabe mit Flags: Private, Commercial; Ausgabe
ohne Flags: 3&lt;/span&gt;&lt;/pre&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Die kombinierten Werte werden also bei gesetztem Flags-Attribut&amp;nbsp;mit Kommata getrennt,&amp;nbsp;statt
einfach als Zahl,&amp;nbsp;ausgegeben. Dies kann sehr nützlich sein. So kann man zum Beispiel
über die Split-Funktion von String so die einzelnen Werte sehr einfach in ein Array
überführen.
&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Fazit&lt;/strong&gt;
&lt;/h4&gt;
&lt;p&gt;
Enums bieten also ein sehr einfaches und flexibles Werkzeug, um mit Konstanten Werten
zu hantieren. Gerade Anfänger lassen sich zu gerne von der Flags-Funktion abschrecken,
da sie so sehr nach "Bits rumschieben" schmeckt. Die Beispiele zeigen jedoch, dass
die Anwendung denkbar einfach und dafür umso Leistungsfähiger ist.
&lt;/p&gt;
&lt;p&gt;
Hier noch&amp;nbsp;zwei interessante&amp;nbsp;Links in diesem Zusammenhang:&lt;br&gt;
&lt;a title="Enum Design-Guidelines von Krzysztof Cwalina" href="http://blogs.msdn.com/kcwalina/archive/2004/05/18/134208.aspx" target="_blank"&gt;Enum
Design-Guidelines von Krzysztof Cwalina&lt;/a&gt;
&lt;br&gt;
&lt;a title="MSDN (C#)" href="http://msdn2.microsoft.com/en-us/library/sbbt4032%28VS.80%29.aspx" target="_blank"&gt;MSDN
(C#)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.nettigkeiten.ch/aggbug.ashx?id=03724581-3463-43a8-bd99-d724bfe05fcb" /&gt;</description>
      <comments>http://blog.nettigkeiten.ch/CommentView,guid,03724581-3463-43a8-bd99-d724bfe05fcb.aspx</c