<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.aspnetzone.de/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang=""><title type="html">Peter Bucher</title><subtitle type="html">Auf den Spuren von .NET</subtitle><id>http://www.aspnetzone.de/blogs/peterbucher/atom.aspx</id><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/default.aspx" /><link rel="self" type="application/atom+xml" href="http://www.aspnetzone.de/blogs/peterbucher/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.61120.2">Community Server</generator><updated>2009-07-28T19:42:00Z</updated><entry><title>ASP / ASP.NET MVP 2010</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2010/01/19/asp-asp-net-mvp-2010.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2010/01/19/asp-asp-net-mvp-2010.aspx</id><published>2010-01-19T19:23:00Z</published><updated>2010-01-19T19:23:00Z</updated><content type="html">&lt;IMG border=0 align=right src="http://www.aspnetzone.de/photos/peterbucher/images/173615/original.aspx"&gt; 
&lt;P&gt;Anfang Jahr erhielt ich eine Email von Microsoft, das ich für das Jahr 2010 renominiert wurde :)&lt;/P&gt;
&lt;P&gt;Das freut mich ungemein und ich möchte mich bei den Betreibern und Moderatoren von &lt;A href="http://www.aspnetzone.de/"&gt;ASP.NET Zone&lt;/A&gt; und &lt;A href="http://mycsharp.de"&gt;myCSharp&lt;/A&gt; bedanken.&lt;BR&gt;Diese Auszeichnung durfte ich jetzt schon das vierte Mal in Folge entgegennehmen, wobei 4 meine Lieblingszahl ist :)&lt;/P&gt;
&lt;P&gt;Sicherlich finde ich die Zeit auch mal in Konstanz beim .NET Stammtisch Konstanz / Kreuzlingen vorbeizuschauen und einen Vortrag zu halten.&lt;/P&gt;
&lt;P&gt;Auf ein erfolgreiches Jahr 2010!&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=215511" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="ASP.NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx" /><category term="MVP" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/MVP/default.aspx" /><category term="Microsoft" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Microsoft/default.aspx" /><category term="Neuigkeiten" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Neuigkeiten/default.aspx" /></entry><entry><title>this oder kein this</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2010/01/01/this-oder-kein-this.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2010/01/01/this-oder-kein-this.aspx</id><published>2010-01-01T08:37:00Z</published><updated>2010-01-01T08:37:00Z</updated><content type="html">&lt;P&gt;Am 13. Oktober 2008 haben &lt;A href="http://www.des-eisbaeren-blog.de/"&gt;Golo Roden&lt;/A&gt; und ich unter dem Titel &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/10/13/noch-fragen-roden-ja-bucher.aspx"&gt;Noch Fragen, Roden? Ja, Bucher!&lt;/A&gt; angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen.&lt;/P&gt;
&lt;P&gt;Bisher sind in dieser Reihe folgende Kommentare erschienen: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;1. Dezember 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/12/01/reflection-fluch-oder-segen.aspx"&gt;Reflection – Fluch oder Segen?&lt;/A&gt;&lt;/EM&gt; 
&lt;LI&gt;&lt;EM&gt;1. November 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/01/wieviel-sinn-machen-unittests.aspx"&gt;Wieviel Sinn machen Unittests?&lt;/A&gt;&lt;/EM&gt; 
&lt;LI&gt;&lt;EM&gt;1. Oktober 2009: Vererben oder aggregieren?&lt;/EM&gt; 
&lt;LI&gt;1. September 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/01/alles-var-oder-nicht.aspx"&gt;Alles var – oder nicht?&lt;/A&gt; 
&lt;LI&gt;1. August 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/08/01/c-oder-vb-welche-sprache-soll-ich-lernen.aspx"&gt;C# oder VB: Welche Sprache soll ich lernen?&lt;/A&gt; 
&lt;LI&gt;1. Juli 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/07/01/prim-rschl-ssel-guid-vs-identity.aspx"&gt;Primärschlüssel: GUID vs Identity&lt;/A&gt; 
&lt;LI&gt;1. Juni 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/06/01/heisst-die-zukunft-ria.aspx"&gt;Heißt die Zukunft RIA?&lt;/A&gt; 
&lt;LI&gt;1. Mai 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/05/01/woran-erkennt-man-einen-guten-entwickler.aspx"&gt;Woran erkennt man einen guten Entwickler?&lt;/A&gt; 
&lt;LI&gt;1. April 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/04/01/interfaces-vs-abstrakte-klassen.aspx"&gt;Interfaces vs abstrakte Klassen&lt;/A&gt; 
&lt;LI&gt;1. März 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/03/01/sinn-und-zweck-von-aop.aspx"&gt;Sinn und Zweck von AOP&lt;/A&gt; 
&lt;LI&gt;1. Februar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/02/01/die-forderung-nach-softwarequalit-t.aspx"&gt;Die Forderung nach Softwarequalität&lt;/A&gt; 
&lt;LI&gt;1. Januar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/01/01/soa-vs-woa.aspx"&gt;SOA vs WOA&lt;/A&gt; 
&lt;LI&gt;1. Dezember 2008: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/12/01/dynamic-language-runtime-net-quo-vadis.aspx"&gt;Dynamic Language Runtime: .NET, quo vadis?&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Heute, am 1. Januar 2010, ist es nun wieder so weit, und unser Thema für diesen Monat lautet: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;this oder kein this&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So wohl Golo wie auch ich haben uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen. &lt;A href="http://www.des-eisbaeren-blog.de/post/2010/01/01/this-oder-kein-this.aspx"&gt;Golos Kommentar&lt;/A&gt; findet sich zeitgleich in seinem Blog, folgend nun mein Kommentar zu diesem Thema.&lt;/P&gt;
&lt;P&gt;Generell ist es sinnvoll, wenn ohne weiteres Zutun gleich erfasst werden kann, ob es sich um eine lokale, statische oder instanzbehaftete Variable handelt. &lt;BR&gt;Aus diesem Grund gibt es Konventionen, wie etwas auszusehen hat, sei dies mit Pascal- (fooBar) / Camel-Casing (FooBar) oder durch Prä- / Postfixe (m_foo, foo_m).&lt;/P&gt;
&lt;P&gt;Im Allgemeinen hat es sich bei mir so entwickelt, dass ich mich immer mehr zu der empfohlenen Microsoft Konvention hin bewegt habe, was die Einarbeitung in andere Projeke um einiges leichter macht, &lt;BR&gt;da diese Konvention häufig – wenn auch teilweise abgeändert – verwendet wird.&lt;/P&gt;
&lt;P&gt;Im aktuellen Streitgespräch geht es darum, ob this verwendet wird / nicht verwendet wird und wo es verwendet wird.&lt;/P&gt;
&lt;P&gt;this wird zwanghaft benötigt, um auf die Referenz auf sich selber, in die Hand zu bekommen. &lt;BR&gt;Beispielsweise wenn in einer User-Klasse eine .Save-Methode angeboten wird, die ihrerseits aber einen Service benutzt um sich speichern zu lassen:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; User &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Save() &lt;br /&gt;    { &lt;br /&gt;        ServiceLocator &lt;br /&gt;                .Resolve&amp;lt;IUserService&amp;gt;() &lt;br /&gt;                .Save(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;); &lt;br /&gt;    } &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Erweiterungsmethoden benutzen this als Kennzeichnung:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; ForEach&amp;lt;T&amp;gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; source, Action&amp;lt;T&amp;gt; action) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;foreach&lt;/span&gt; (var item &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; source) &lt;br /&gt;    { &lt;br /&gt;        action(item); &lt;br /&gt;    } &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Bei einer Indexerdeklaration wird this auch benötigt:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; User &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;[sring index]&lt;br /&gt;{&lt;br /&gt;   get { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;._list[index]; }&lt;br /&gt;   set { &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;._list[index] &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; value; }&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Ein andere Stelle wo this benutzt werden muss, ist beim angeben von zusätzlichen Konstruktoren von sich selbst, die auch noch aufgerufen werden sollen:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; UserService &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;readonly&lt;/span&gt; IRepository&amp;lt;User&amp;gt; _userRepository; &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; UserService() : &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; XmlUserRepository()) &lt;br /&gt;    { &lt;br /&gt;        &lt;br /&gt;    } &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; UserService(IRepository&amp;lt;User&amp;gt; userRepository) &lt;br /&gt;    { &lt;br /&gt;         _userRepository &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; userRepository; &lt;br /&gt;    } &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Im ersten Konstruktor wird angegeben, das auch der zweite Konstruktor mit einem Parameter aufgerufen werden soll.&lt;/P&gt;
&lt;P&gt;Wenn die Instanzvariable “_userRepository” keinen Unterstrich hätte – also “userRepository” – müsste this verwendet werden, damit der Kompiler zwischen Instanzvariable und Argument unterscheiden kann, also:&lt;/P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;readonly&lt;/span&gt; IRepository&amp;lt;User&amp;gt; userRepository; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; UserService(IRepository&amp;lt;User&amp;gt; userRepository) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.userRepository &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; userRepository; &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt; 
&lt;P&gt;Zu Anfang habe ich das Präfix “_” vor einer Instanzvariable benutzt, so kann man – auch im Intellisense – ohne Probleme auswählen und unterscheiden, da alle schön gruppiert sind. &lt;BR&gt;&lt;BR&gt;In Visual Studio 2005 gab es allerdings kein Intellisense bei der Eingabe von “_test” im Code-Editor. &lt;BR&gt;Ich habe dort “this._test” genutzt, denn es ist ja ein Instanzmember und mit der Eingabe von “this.” gab es dann Intellisense.&lt;/P&gt;
&lt;P&gt;Ab Visual Studio 2008 gibt es bereits bei der Eingabe von “_” Intellisense, somit wäre “this” überflüssig. Allerdings habe ich mir angewöhnt, this überall anzugeben, wo sich etwas auf die Instanz bezieht.&lt;/P&gt;
&lt;P&gt;Also für Methodenaufrufe auf der Instanz (in der Regel protected oder private Methoden), Eigenschaften sowie Instanzfelder. &lt;BR&gt;Es ist so möglich auf den ersten Blick zu unterscheiden und erfassen, was eine lokale Variable ist, was ein statisches Feld / Konstante. Oder doch eine Instanzvariable?.&lt;/P&gt;
&lt;P&gt;Was meint ihr dazu?&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=216045" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="C#" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/C_2300_/default.aspx" /><category term="Streitgespr&amp;#228;ch" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Streitgespr_26002300_228_3B00_ch/default.aspx" /><category term="this" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/this/default.aspx" /></entry><entry><title>InternalsVisibleToAttribute und signierte Assemblies: So funktionierts garantiert.</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/12/04/internalsvisibletoattribute-und-signierte-assemblies-so-funktionierts-garantiert.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/12/04/internalsvisibletoattribute-und-signierte-assemblies-so-funktionierts-garantiert.aspx</id><published>2009-12-04T15:46:00Z</published><updated>2009-12-04T15:46:00Z</updated><content type="html">&lt;P&gt;Stellt euch vor, ihr habt zwei Assemblies:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;MyProject.Core 
&lt;LI&gt;MyProject.Core.Tests &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Im Core-Projekt gibt es Typen, die nicht öffentlich gemacht werden sollten, allerdings für die UnitTests zugänglich sein sollen. &lt;BR&gt;Nun, das ist ein kleines Problem, wenn man das Attribut “InternalsVisibleTo” kennt, mithilfe folgender Dekleration in der &lt;STRONG&gt;AssemblyInfo.cs des MyProject.Core-Projekts&lt;/STRONG&gt; kann dies einfach erledigt werden:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;[assembly: InternalsVisibleTo("MyProject.Core.Tests”)]&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;DIV class=Quotes&gt;&lt;BR =&gt;Das macht sogar sehr viel Sinn, denn sonst können Kollisionen und Verwechslungen der Extensionmethods beim Endbenutzer vorkommen.&lt;/DIV&gt;
&lt;P&gt;Soweit, so gut. Die Typen der MyProject.Core-Assembly sind jetzt in der MyProject.Core.Tests-Assembly sichtbar. &lt;BR&gt;Müssen die Projekte jedoch signiert sein, kommt es zu einem grösseren Problem.&lt;/P&gt;
&lt;P&gt;In &lt;A href="http://www.sturmnet.org/blog/2005/05/10/internalsvisibleto-sn"&gt;mehreren&lt;/A&gt; Blogs sind die nötigen Schritte &lt;A href="http://weblogs.asp.net/bhouse/archive/2006/04/17/443100.aspx"&gt;beschrieben&lt;/A&gt;, &lt;U&gt;jedoch werden da wichtige Punkte nicht genannt&lt;/U&gt;, die einem zur Verzweiflung treiben können. &lt;BR&gt;Die sind wie folgt:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Alle involvierten Assemblies müssen signiert werden. 
&lt;LI&gt;Der PublicKey muss vom Projekt bezogen werden, bei dem die Internals sichtbar werden sollen, in unserem Fall also das MyProject.Core.Tests-Projekt. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Nach einer weiteren Suche bin ich schlussendlich auf einem (selbsternannten) Newbie-Blog fündig geworden. &lt;BR&gt;Noch später sties ich dann auf die folgende Anleitung, die eigentlich alles beinhaltet, sodass ich nicht alles im Detail niederschreiben muss, trotzdem die wichtigen Punkte nennen kann und vorallem die Lösung wieder einmal finde:&lt;/P&gt;
&lt;P&gt;Also, beachtet die oben stehenden zwei Punkte und haltet euch an folgende Anleitung:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A title=http://statestreetgang.net/post/2008/04/InternalsVisibleToAttribute-and-Strong-Named-Assemblies-Step-by-Step.aspx href="http://statestreetgang.net/post/2008/04/InternalsVisibleToAttribute-and-Strong-Named-Assemblies-Step-by-Step.aspx"&gt;http://statestreetgang.net/post/2008/04/InternalsVisibleToAttribute-and-Strong-Named-Assemblies-Step-by-Step.aspx&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=214947" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="Tipps" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Tipps/default.aspx" /><category term=".NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/.NET/default.aspx" /><category term="Assembly" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Assembly/default.aspx" /><category term="InternalsVisibleTo" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/InternalsVisibleTo/default.aspx" /><category term="StrongName" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/StrongName/default.aspx" /></entry><entry><title>Reflection – Fluch oder Segen?</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/12/01/reflection-fluch-oder-segen.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/12/01/reflection-fluch-oder-segen.aspx</id><published>2009-12-01T08:37:00Z</published><updated>2009-12-01T08:37:00Z</updated><content type="html">&lt;P&gt;Am 13. Oktober 2008 haben &lt;A href="http://www.des-eisbaeren-blog.de/"&gt;Golo Roden&lt;/A&gt; und ich unter dem Titel &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/10/13/noch-fragen-roden-ja-bucher.aspx"&gt;Noch Fragen, Roden? Ja, Bucher!&lt;/A&gt; angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen.&lt;/P&gt;
&lt;P&gt;Bisher sind in dieser Reihe folgende Kommentare erschienen: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;1. November 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/01/wieviel-sinn-machen-unittests.aspx"&gt;Wieviel Sinn machen Unittests?&lt;/A&gt;&lt;/EM&gt; 
&lt;LI&gt;&lt;EM&gt;1. Oktober 2009: Vererben oder aggregieren?&lt;/EM&gt; 
&lt;LI&gt;1. September 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/01/alles-var-oder-nicht.aspx"&gt;Alles var – oder nicht?&lt;/A&gt; 
&lt;LI&gt;1. August 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/08/01/c-oder-vb-welche-sprache-soll-ich-lernen.aspx"&gt;C# oder VB: Welche Sprache soll ich lernen?&lt;/A&gt; 
&lt;LI&gt;1. Juli 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/07/01/prim-rschl-ssel-guid-vs-identity.aspx"&gt;Primärschlüssel: GUID vs Identity&lt;/A&gt; 
&lt;LI&gt;1. Juni 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/06/01/heisst-die-zukunft-ria.aspx"&gt;Heißt die Zukunft RIA?&lt;/A&gt; 
&lt;LI&gt;1. Mai 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/05/01/woran-erkennt-man-einen-guten-entwickler.aspx"&gt;Woran erkennt man einen guten Entwickler?&lt;/A&gt; 
&lt;LI&gt;1. April 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/04/01/interfaces-vs-abstrakte-klassen.aspx"&gt;Interfaces vs abstrakte Klassen&lt;/A&gt; 
&lt;LI&gt;1. März 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/03/01/sinn-und-zweck-von-aop.aspx"&gt;Sinn und Zweck von AOP&lt;/A&gt; 
&lt;LI&gt;1. Februar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/02/01/die-forderung-nach-softwarequalit-t.aspx"&gt;Die Forderung nach Softwarequalität&lt;/A&gt; 
&lt;LI&gt;1. Januar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/01/01/soa-vs-woa.aspx"&gt;SOA vs WOA&lt;/A&gt; 
&lt;LI&gt;1. Dezember 2008: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/12/01/dynamic-language-runtime-net-quo-vadis.aspx"&gt;Dynamic Language Runtime: .NET, quo vadis?&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Heute, am 1. Dezember 2009, ist es nun wieder so weit, und unser Thema für diesen Monat lautet: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;Reflection – Fluch oder Segen?&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So wohl Golo wie auch ich haben uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen. &lt;A href="http://www.des-eisbaeren-blog.de/post/2009/12/01/Reflection-e28093-Fluch-oder-Segen.aspx"&gt;Golos Kommentar&lt;/A&gt; findet sich zeitgleich in seinem Blog, folgend nun mein Kommentar zu diesem Thema:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Reflection?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Reflection, &lt;A href="http://de.wikipedia.org/wiki/Reflexion_(Programmierung)"&gt;Reflexion&lt;/A&gt; bzw. Introspektion macht es möglich, Programme wie Daten zu behandeln und so Informationen über Typen / Member abzurufen und auch zu setzen. &lt;/P&gt;
&lt;P&gt;Eine Einführung zu Reflection findet sich bspw. &lt;A href="http://www.aspheute.com/artikel/20040624.htm"&gt;hier&lt;/A&gt;, und auf myCSharp.de findet sich ein &lt;A href="http://www.mycsharp.de/wbb2/thread.php?threadid=68247"&gt;super ausführlicher und tiefgehender Artikel&lt;/A&gt;, der auf jeden Fall lesenswert ist. &lt;BR&gt;Darüber hinaus ist es per Reflection möglich, eine späte Bindung in jeglicher Hinsicht zu erreichen. Sei dies das dynamische Laden einer Assembly oder auch das dynamische Aufrufen einer Methode zur Laufzeit.&lt;BR&gt;Damit lassen sich Service Locator und Dependency Injection Container - also Systeme zur Entkoppelung - umsetzen, die je nach Konfiguration eine andere Assembly mitsamt ihren Typen lädt.&lt;/P&gt;
&lt;P&gt;Ein praktischer Anwendungsfall wäre ein Serialisierungsmechanismus, der Objekthierarchien bspw. in XML-Form abspeichern kann. &lt;BR&gt;Mithilfe von Reflection können die zu speichernden Typen in Form einer Instanz von &lt;A href="http://msdn.microsoft.com/de-de/library/system.type.aspx"&gt;System.Reflection.Type&lt;/A&gt; abgefragt werden.&lt;/P&gt;
&lt;P&gt;Ein Type Objekt macht alles verfügbar, was zu einem Typen gehört, seien dies Methoden, Attribute, Eigenschaften oder gar Felder.&lt;/P&gt;
&lt;P&gt;Kleines Beispiel:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; count &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 2012; &lt;br /&gt;Type typeOfCount &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; count.GetType(); &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Oder: typeof(int)&lt;/span&gt;&lt;br /&gt;Console.WriteLine(typeOfCount); &lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Ausgabe ist die Stringrepräsentation des Types der mit dem Alias int verknüpft ist, also: “System.Int32”.&lt;/P&gt;
&lt;P&gt;Schluss ist damit noch lange nicht, es ist genau so möglich Code zur Kompile- oder Laufzeit dynamisch zu erstellen. &lt;BR&gt;Das .NET Framework bietet die hierzu nötigen Klassen im Namensraum &lt;A href="http://msdn.microsoft.com/de-de/library/system.reflection.emit(VS.80).aspx"&gt;System.Reflection.Emit&lt;/A&gt; bereit.&lt;/P&gt;
&lt;P&gt;Die Anwendung dieser API ist jedoch relativ umständlich und komplex, dafür extrem mächtig.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Segen?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Reflection und Bibliotheken die darauf aufbauen birgen ein riesen Potential und ungeahnte Möglichkeiten. &lt;BR&gt;Die Anwendung ist extrem einfach und viele Features im .NET Framework selber bauen auch auf Reflection auf.&lt;/P&gt;
&lt;P&gt;Also auf jeden Fall ein Segen… auf der einen Seite.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Fluch?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Auf der anderen Seite kann es auch zu einem Fluch werden, denn mit Reflection kann viel Humbug getrieben werden. &lt;BR&gt;Zum einen ist die Ausführung von Code der Reflection nutzt, um einiges langsamer, was zu Performanceproblemen führen kann, zum anderen kann so auch die Mauer der Zugriffsmodifizierer umgangen werden, da es ohne viel Aufwand möglich ist, auch private Members einer Klasse auszulesen.&lt;/P&gt;
&lt;P&gt;Zudem können Probleme auftreten, wenn die Umgebung in der eine Anwendung läuft, zuwenig Rechte hat. Das kann dazu führen, das eine Anwendung überhaupt nicht, oder nur eingeschränkt lauffähig ist, in restriktiven Umgebungen.&lt;/P&gt;
&lt;P&gt;Über das dynamische Laden von Assemblies kann es zu Sicherheitsproblemen kommen, falls die geladenen Assemblies schädlichen Code enthalten.&lt;/P&gt;
&lt;P&gt;Allerdings lassen sich viele der geschilderten Probleme umgehen bzw. beheben. &lt;BR&gt;Caching – dafür gibt es auch schon &lt;A href="http://www.codeproject.com/KB/cs/fast_dynamic_properties.aspx"&gt;diverse&lt;/A&gt;, &lt;A href="http://www.codeproject.com/KB/library/fasterflect_.aspx"&gt;fertige&lt;/A&gt; APIs, die auch neben Caching noch weitere Verbesserungen für Reflection bringen.&lt;/P&gt;
&lt;P&gt;Alle anderen Probleme brauchen eine vorsichtige und sparsame Verwendung von Reflection. &lt;BR&gt;Mein Credo dabei ist: &lt;U&gt;So viel wie nötig, so wenig wie möglich&lt;/U&gt;. Denn sehr vieles geht auch ohne Reflection, kann aber mit Reflection nachgebaut werden.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;System.Linq.Expressions&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Mit der Einführung von LINQ und in dessen Zuge auch dem neuen Namensraum &lt;A href="http://msdn.microsoft.com/de-de/library/system.linq.expressions(VS.95).aspx"&gt;System.Linq.Expressions&lt;/A&gt; gibt es eine weitere und einfachere Möglichkeit, Code dynamisch zu generieren und vorallem auch zu analysieren.&lt;/P&gt;
&lt;P&gt;Zum einen ist es mit LINQ und den Expression Trees möglich, Lambda Ausdrücke, die in eine Methode eingespiesen werden, auseinander zu nehmen und zu analysieren. &lt;BR&gt;In .NET selber wird das bspw. verwendet, um LINQ abfragen zu parsen und diese anschliessend in ein SQL-Statement zu überführen.&lt;/P&gt;
&lt;P&gt;Zumindest laut meinem Wissen, ist es mit dem Expressions-API nur möglich, Methoden dynamisch zu generieren und zu kompilieren. Das ist eine Einschränkung, die allerdings für viele Anwendungsfälle nicht weiter tragisch ist, damit lässt einfach schon relativ viel realisieren.&lt;/P&gt;
&lt;P&gt;Das Expressions-API nutzt intern auch Reflection und schlussendlich auch die Klassen aus dem Namensraum System.Reflection.Emit.&lt;/P&gt;
&lt;P&gt;Beispiele mit dem Expressions-API:&lt;/P&gt;Addieren von zwei Zahlen per statischem Code. &lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; AddPlain() &lt;br /&gt;{ &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; one &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 1; &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; two &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 2; &lt;br /&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; result &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; one &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;+&lt;/span&gt; two; &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Addieren von zwei Zahlen, die Methode wird dynamisch zusammengebaut. &lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; AddWithExpressions() &lt;br /&gt;{ &lt;br /&gt;  ConstantExpression numberOneExpression &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Expression.Constant(2); &lt;br /&gt;  ConstantExpression numberTwoExpression &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Expression.Constant(3); &lt;br /&gt;&lt;br /&gt;  BinaryExpression addExpression &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Expression.Add(numberOneExpression, numberTwoExpression); &lt;br /&gt;&lt;br /&gt;  var lambdaExpression &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Expression.Lambda&amp;lt;Func&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;(addExpression); &lt;br /&gt;  Func&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt; methodDelegate &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; lambdaExpression.Compile(); &lt;br /&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; result &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; methodDelegate(); &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt;&lt;BR&gt;&lt;BR&gt;Funktion zum Addieren von zwei Zahlen per statischm Code. &lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; AddFunctionPlain(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; left, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; right) &lt;br /&gt;{ &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; left &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;+&lt;/span&gt; right; &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Funktion zum Addieren von zwei Zahlen dynamische generiert. &lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; Func&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt; GenerateAddFunction() &lt;br /&gt;{ &lt;br /&gt;  ParameterExpression leftParameter &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Expression.Parameter(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;typeof&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;), &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"left"&lt;/span&gt;); &lt;br /&gt;  ParameterExpression rightParameter &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Expression.Parameter(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;typeof&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;), &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"right"&lt;/span&gt;); &lt;br /&gt;&lt;br /&gt;  BinaryExpression addExpression &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Expression.Add(leftParameter, rightParameter); &lt;br /&gt;&lt;br /&gt;  var lambdaExpression &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Expression.Lambda&amp;lt;Func&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;(addExpression, leftParameter, rightParameter); &lt;br /&gt;  Func&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt; methodDelegate &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; lambdaExpression.Compile(); &lt;br /&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; methodDelegate; &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Wie man sehen kann, ist die Nutzung von Expressions zum dynamische Generieren von Methoden für Ihre Mächtigkeit immer noch relativ einfach zu nutzen.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Fazit&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Das war ein kurzer Rundflug durch Reflection und verwandte Gebiete, in dem ich versucht habe, die Vorteile, Möglichkeiten sowie auch Gefahren aufzuzeigen. &lt;BR&gt;Reflection ist genial, aber nur wenn es sinngemäss und mit Vorsicht eingesetzt wird.&lt;/P&gt;
&lt;P&gt;Also: Fluch und Segen :)&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=214864" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term=".NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/.NET/default.aspx" /><category term="Streitgespr&amp;#228;ch" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Streitgespr_26002300_228_3B00_ch/default.aspx" /><category term="Type" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Type/default.aspx" /><category term="Lambda" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Lambda/default.aspx" /><category term="LINQ" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/LINQ/default.aspx" /><category term="Expressions" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Expressions/default.aspx" /><category term="Reflection" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Reflection/default.aspx" /><category term="Reflexion" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Reflexion/default.aspx" /></entry><entry><title>Wann IEnumerable nutzen, wann ICollection und wieso überhaupt IList?</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/19/wann-ienumerable-nutzen-wann-icollection-und-wieso-berhaupt-ilist.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/19/wann-ienumerable-nutzen-wann-icollection-und-wieso-berhaupt-ilist.aspx</id><published>2009-11-19T17:09:00Z</published><updated>2009-11-19T17:09:00Z</updated><content type="html">&lt;P&gt;Es gibt einige Mengen- /&amp;nbsp; Auflistungstypen in .NET.&lt;/P&gt;
&lt;P&gt;Ein kleine Auswahl:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/de-de/library/system.array(VS.80).aspx"&gt;Array&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/de-de/library/6sh2ey19.aspx"&gt;List&amp;lt;T&amp;gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/de-de/library/3278tedw.aspx"&gt;Stack&amp;lt;T&amp;gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/de-de/library/7977ey2c.aspx"&gt;Queue&amp;lt;T&amp;gt;&lt;/A&gt; 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/de-de/library/xfhwa508.aspx"&gt;Dictionary&amp;lt;T&amp;gt;&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Früher gab es nur nicht generische bzw. keine stark typisierte Collections, die heute nicht mehr verwendet werden sollten, &lt;BR&gt;da immer explizit gecastet werden muss, was umständlich ist und Performance kostet.&lt;/P&gt;
&lt;P&gt;Hierfür zitiere ich gerne herbivore aus myCSharp:&lt;/P&gt;
&lt;DIV class=Quotes&gt;
&lt;P&gt;ArrayList gehört in die Mottenkiste und sollte wie alle untypisierten Collections aus System.Collections nicht mehr benutzt werden. Verwende stattdessen List&amp;lt;T&amp;gt; und alle anderen typisierten Collections aus System.Collections.Generic. &lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Ich möchte hier allerdings nicht die verschiedenen Auflistungstypen im Detail anschauen, sondern herausfinden, &lt;STRONG&gt;wann welcher konkreter Typ&lt;/STRONG&gt; oder gar das Interface in einer Signatur &lt;STRONG&gt;verwendet werden sollte&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Ein kleines Beispiel:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; PrintNamesToConsole(List&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;&amp;gt; names) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;foreach&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; names) &lt;br /&gt;    { &lt;br /&gt;        Console.WriteLine(name); &lt;br /&gt;    } &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Dieser Code verwendet List&amp;lt;T&amp;gt; als Argumenttyp, es besteht also eine Abhängigkeit darauf, &lt;BR&gt;d.h. jeder Aufrufer muss hier eine List&amp;lt;T&amp;gt; übergeben, alles andere funktioniert nicht. &lt;BR&gt;Beispielsweise kann hier kein Array übergeben werden, oder eine Collection.&lt;/P&gt;
&lt;P&gt;Wenn dann innerhalb der Methode, die das Argument entgegennimmt, nicht einmal &lt;BR&gt;auf spezifische Methoden / Eigenschaften des konkreten Types (List&amp;lt;T&amp;gt;) zugegriffen wird, &lt;BR&gt;ist das noch ein grösser Nachteil, denn man erkauft sich eine Abhängigkeit, ohne das man sie eigentlich benötigt.&lt;/P&gt;
&lt;P&gt;Hört sich komisch an? &lt;BR&gt;Eigentlich ist es relativ leicht, wenn wir uns mal die verschiedenen Schnittstellen betrachten, worauf die Auflistungen in .NET aufbauen.&lt;/P&gt;
&lt;P&gt;Der eigentliche Kern ist die Schnittstelle &lt;A href="http://msdn.microsoft.com/de-de/library/system.collections.ienumerable(VS.80).aspx"&gt;IEnumerable&lt;/A&gt; bzw. der typisierte Bruder &lt;A href="http://msdn.microsoft.com/de-de/library/9eekhta0.aspx"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/A&gt;, wobei dort T den Typ der enthaltenen Elemente angibt.&lt;/P&gt;
&lt;P&gt;IEnumerable: &lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;interface&lt;/span&gt; IEnumerable &lt;br /&gt;{ &lt;br /&gt;    IEnumerator GetEnumerator(); &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;IEnumerable&amp;lt;T&amp;gt;: &lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;interface&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; : IEnumerable &lt;br /&gt;{ &lt;br /&gt;    IEnumerator&amp;lt;T&amp;gt; GetEnumerator(); &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Das Interface IEnumerator sieht dann so aus: &lt;BR&gt;(Die generische Implementation &lt;A href="http://msdn.microsoft.com/de-de/library/78dfe2yb.aspx"&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/A&gt;, hat zusätzlich eine Eigenschaft vom Typ T über die Eigenschaft &lt;A href="http://msdn.microsoft.com/de-de/library/58e146b7.aspx"&gt;Current&lt;/A&gt;). &lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;interface&lt;/span&gt; IEnumerator &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;bool&lt;/span&gt; MoveNext(); &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;object&lt;/span&gt; Current { get; } &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Reset(); &lt;br /&gt;} &lt;/span&gt;&lt;/code&gt; &lt;BR&gt;&lt;/P&gt;
&lt;P&gt;Anhand der Beispiele ist zu sehen, das IEnumerable / IEnumerable&amp;lt;T&amp;gt; und die dazugehörige Schnittstelle für den &lt;BR&gt;Enumerator beschreibt, das Elemente durchlaufen werden können. Nicht mehr und nicht weniger.&lt;/P&gt;
&lt;P&gt;Das Beispiel von oben, könnte wie folgt umgeschrieben werden, um die kleinste Abhängigkeit zu haben und trotzdem &lt;BR&gt;alle Anforderungen funktionieren, denn es muss ja nur eine Auflistung durchlaufen werden, nicht mehr und nicht weniger.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; PrintNamesToConsole(IEnumerable&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;&amp;gt; names) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;foreach&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; name &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; names) &lt;br /&gt;    { &lt;br /&gt;        Console.WriteLine(name); &lt;br /&gt;    } &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Man beachte den geänderten Argumenttyp, der jetzt viel genereller ist. &lt;BR&gt;Jetzt kann die Methode ein string[], eine List&amp;lt;T&amp;gt;, … entgegennehmen, einfach alles das die Schnittstelle IEnumerable&amp;lt;T&amp;gt; implementiert.&lt;/P&gt;
&lt;P&gt;Wird eine Unterstützung in der Art von &amp;lt;Auflistung&amp;gt;.Count gefordert, kann die Schnittstelle &lt;A href="http://msdn.microsoft.com/de-de/library/92t2ye13.aspx"&gt;ICollection&amp;lt;T&amp;gt;&lt;/A&gt; angegeben werden, die eine solche Eigenschaft nativ mitbringt. &lt;BR&gt;Zusätzlich beschreibt das Interface (Erst ab der generischen Variante), das ein Element hinzugefügt, die Auflistung geleert, zurückgeben kann ob ein Element exisitert und Elemente entfernt werden können.&lt;/P&gt;
&lt;P&gt;Durch LINQ to Objects können praktisch alle Operationen, wie bspw. Anzahl Elemente abfragen, sortieren, filtern, Zugriff über Index, damit und auf dem IEnumerable&amp;lt;T&amp;gt; Typen gemacht werden. &lt;BR&gt;LINQ to Objects ist schnell, sehr schnell sogar. Wird jedoch die höchste Leistung benötigt und bspw. sehr häufig auf die .Count-Eigenschaft zugegriffen, &lt;BR&gt;ist es besser, wenn eine native Unterstützung einer solchen Eigenschaft vorliegt.&lt;/P&gt;
&lt;P&gt;LINQ to Objects arbeitet bei Count ungefähr so:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Versuche die Auflistung nach ICollection&amp;lt;T&amp;gt; zu casten. 
&lt;LI&gt;Wenn das klappt, rufe die .Count-Eigenschaft ab und gib das Ergebnis zurück. 
&lt;LI&gt;Wenn es nicht klappt, durchlaufe alle Einträge in der Auflistung, zähle die Anzahl zusammen und gib das Ergebnis zurück. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Das Interface &lt;A href="http://msdn.microsoft.com/de-de/library/5y536ey6.aspx"&gt;IList&amp;lt;T&amp;gt;&lt;/A&gt; selber implementiert ICollection&amp;lt;T&amp;gt; – kann also alles auch – jedoch gibt es zusätzlich noch die Möglichkeit nativ per Index zu arbeiten. Also Elemente indexiert abfragen, ein Element an einem bestimmten Index löschen / einfügen.&lt;/P&gt;
&lt;P&gt;In den meisten Fällen reicht es also, wenn IEnumerable&amp;lt;T&amp;gt; als Argumenttyp bzw. Rückgabetyp angegeben wird und in den anderen Fällen jeweils das Interface ICollection&amp;lt;T&amp;gt; / IList&amp;lt;T&amp;gt;, je nachdem was benötigt wird.&lt;/P&gt;
&lt;P&gt;Es ist zu beachten, das IList&amp;lt;T&amp;gt; nicht alles beschreibt, was List&amp;lt;T&amp;gt; implementiert, bspw. gibt es dann keine Find- / FindAll-Methode, sowie auch keine native Implementierung für das Sortieren. &lt;BR&gt;Mit LINQ to Objects tritt das allerdings in den Hintergrund und so kann man sich im Code von Abhängigkeiten zu den konkreten Auflistungstypen lösen.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Wieso soll man sich überhaupt lösen?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Umso&amp;nbsp;genereller die Argument- oder Rückgabetypen sind, desto flexibler ist die API und es wird nicht mehr öffentlich gemacht, als schlussendlich verwendet wird. &lt;BR&gt;Zusätzlich ist die Abhängigkeit zu einem konkreten Typ weg, was bedeutet das bspw. anstelle einer List&amp;lt;T&amp;gt; einfach irgend eine andere Implementierung von IEnumerable&amp;lt;T&amp;gt; empfangen / zurückgegeben werden kann.&lt;/P&gt;
&lt;P&gt;So kann bspw. später eine Auflistung implementiert werden, die bei einem bestimmten Ereignis wie bspw. das Entfernen eines Eintrages, einen Event auslöst, ohne den Argumenttyp zu ändern.&lt;/P&gt;
&lt;P&gt;Folgend noch ein paar sehr interessante Beiträge zum Thema:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A title=http://elegantcode.com/2008/04/07/replace-your-collections-with-ienumerablet/ href="http://elegantcode.com/2008/04/07/replace-your-collections-with-ienumerablet/"&gt;http://elegantcode.com/2008/04/07/replace-your-collections-with-ienumerablet/&lt;/A&gt; 
&lt;LI&gt;&lt;A title=http://flimflan.com/blog/ThePowerOfYieldReturn.aspx href="http://flimflan.com/blog/ThePowerOfYieldReturn.aspx"&gt;http://flimflan.com/blog/ThePowerOfYieldReturn.aspx&lt;/A&gt; 
&lt;LI&gt;&lt;A title=http://blogs.msdn.com/kcwalina/archive/2005/09/23/Collections.aspx href="http://blogs.msdn.com/kcwalina/archive/2005/09/23/Collections.aspx"&gt;http://blogs.msdn.com/kcwalina/archive/2005/09/23/Collections.aspx&lt;/A&gt; 
&lt;LI&gt;&lt;A title=http://blog.voidnish.com/?p=190 href="http://blog.voidnish.com/?p=190"&gt;http://blog.voidnish.com/?p=190&lt;/A&gt; 
&lt;LI&gt;&lt;A title=http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/e5d1f77e-fb42-40f9-b44c-8c218bcdac18 href="http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/e5d1f77e-fb42-40f9-b44c-8c218bcdac18"&gt;http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/e5d1f77e-fb42-40f9-b44c-8c218bcdac18&lt;/A&gt; 
&lt;LI&gt;&lt;A title=http://www.informit.com/guides/content.aspx?g=dotnet&amp;amp;seqNum=722 href="http://www.informit.com/guides/content.aspx?g=dotnet&amp;amp;seqNum=722"&gt;http://www.informit.com/guides/content.aspx?g=dotnet&amp;amp;seqNum=722&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=214672" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="Artikel" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Artikel/default.aspx" /><category term=".NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/.NET/default.aspx" /><category term="LINQ" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/LINQ/default.aspx" /><category term="Auflistungen" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Auflistungen/default.aspx" /><category term="IEnumerable" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/IEnumerable/default.aspx" /><category term="Collections" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Collections/default.aspx" /></entry><entry><title>Fehler verstecken leicht gemacht</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/13/fehler-verstecken-leicht-gemacht.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/13/fehler-verstecken-leicht-gemacht.aspx</id><published>2009-11-13T13:52:00Z</published><updated>2009-11-13T13:52:00Z</updated><content type="html">&lt;P&gt;Mit &lt;A href="http://msdn.microsoft.com/de-de/library/fk6t46tz.aspx"&gt;Try / Catch / Finally&lt;/A&gt; können in .NET Fehler behandelt werden. &lt;BR&gt;Eigentlich eine gute Sache, allerdings sollte man aufpassen wo und wie man Fehler behandelt.&lt;/P&gt;
&lt;P&gt;Vielerorts kann gelesen werden, dass das Fangen einer Allgemeinen Exception nicht gut sei, aber wieso ist das so?&lt;/P&gt;
&lt;P&gt;Da ich es auch schon selber praktisch mehrmals erlebt habe, was das für &lt;STRONG&gt;&lt;U&gt;schlimme&lt;/U&gt;&lt;/STRONG&gt; Auswirkungen haben kann, ist es für mich nicht so schwer, diese Frage zu beantworten.&lt;/P&gt;
&lt;P&gt;Ich möchte dies anhand eines kleinen, nachvollziehbaren Beispiel erläutern.&lt;/P&gt;
&lt;P&gt;Gegeben ist folgender Code:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;protected&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;object&lt;/span&gt; sender, EventArgs e) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.GridView1.DataSource &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &amp;lt;DataSource&amp;gt;; &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.GridView1.RowDataBound += GridView1_RowDataBound; &lt;br /&gt;        CommandField deleteField &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; CommandField &lt;br /&gt;                   { &lt;br /&gt;                     ShowDeleteButton &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; !&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;._recordsAreReadOnly,&lt;br /&gt;                     DeleteText &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; “Löschen”, &lt;br /&gt;                     DeleteImageUrl &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"delete.png"&lt;/span&gt;, &lt;br /&gt;                     ButtonType &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; ButtonType.Image&lt;br /&gt;                   }; &lt;br /&gt;&lt;br /&gt;         GridView1.Columns.Add(deleteField); &lt;br /&gt;        &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// zusätzlichen Code… &lt;/span&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.GridView.DataBind(); &lt;br /&gt;    } &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;catch&lt;/span&gt;(Exception ex) &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.Logger.Log(ex); &lt;br /&gt;    } &lt;br /&gt;} &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;protected&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; GridView1_RowDataBound(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;object&lt;/span&gt; sender, GridViewRowEventArgs e) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(e.Row.RowType == DataControlRowType.DataRow) &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// zusätzlicher Code… &lt;/span&gt;&lt;br /&gt;        ImageButton deleteButton &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; e.Row.FindControlRecursive&amp;lt;ImageButton&amp;gt;(c =&amp;gt; c.CommandName == “Delete”); &lt;br /&gt;        deleteButton.CssClass &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; “button_delete”; &lt;br /&gt;        &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// zusätzlicher Code… &lt;/span&gt;&lt;br /&gt;    } &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Dieser Code, läuft - wie er jetzt da steht - ohne Probleme, solange die Daten nie als readonly gekennzeichnet werden. &lt;BR&gt;Wird jetzt allerdings der Code erweitert, gibt es ein höchst merkwürdiges Verhalten, das ich mir zuerst überhaupt nicht erkären konnte.&lt;/P&gt;
&lt;P&gt;Folgende Änderung:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;ShowDeleteButton &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; !&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;._recordsAreReadOnly,&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;&lt;/CODE&gt;
&lt;P&gt;wird zu:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;ShowDeleteButton &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; !&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;._recordsAreReadOnly &amp;amp;&amp;amp; &amp;lt;Sicherheitsabfrage ob gelöscht werden darf&amp;gt;,&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Der erste Teil der Bedingung liefert mit der Negation schlussendlich true und die Sicherheitsabfrage false, was ausgewertet dann einem false entspricht. &lt;BR&gt;Somit werden die Löschen-Buttons nicht dargestellt. Gut. Eigentlich genau das was ich wollte.&lt;/P&gt;
&lt;P&gt;Jedoch – und jetzt kommt der Haken – wird jetzt nur noch ein Datensatz im GridView angezeigt, anstelle von den zwei die in der Datenquelle vorhanden sind.&lt;/P&gt;
&lt;P&gt;Im ersten Moment kam mir das ziemlich merkwürdig vor, da ich auch nirgendwo nochmals auf die Bedingung zugreifen und vor allem, weil auch kein Fehler geworfen wurde.&lt;/P&gt;
&lt;P&gt;Kurz nachdem ich den Debugger angeworfen und kurz in den EventHandler “GridView1_RowDataBound” reingeschaut habe, kam es mir in den Sinn:&lt;/P&gt;
&lt;P&gt;Böses Try / Catch, &lt;STRONG&gt;ein Fehler&lt;/STRONG&gt; wurde &lt;STRONG&gt;versteckt&lt;/STRONG&gt;, ohne das ich es gemerkt habe.&lt;/P&gt;
&lt;P&gt;Was ist denn genau passiert?&lt;/P&gt;
&lt;P&gt;Nun, da über die komplette &lt;EM&gt;Page_Load-Methode&lt;/EM&gt; ein Try / Catch Konstrukt gespannt ist, das generell alle Fehler abfängt (Nicht behandelt, sondern eben “verschluckt”), bekomme ich den Fehler nicht zu Gesicht und der Code &lt;STRONG&gt;läuft&lt;/STRONG&gt; in einem &lt;STRONG&gt;inkonsistenten Zustand weiter&lt;/STRONG&gt;. &lt;/P&gt;
&lt;P&gt;Der Eventhandler wird angemeldet und durch den &lt;EM&gt;GridView1.DataBind()&lt;/EM&gt; Aufruf, läuft auf der Eventhandler selber im Scope von besagtem Try / Catch, sodass die NullReferenceException, &lt;STRONG&gt;die eigentlich geworfen werden sollte, &lt;U&gt;verschluckt wird&lt;/U&gt;&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Das hat dann dazu geführt, dass das GridView “irgendwie” noch halb fertig gerendert wird und man nichts vom Fehler mitbekommt, sondern eben nur einen Datensatz halb fertig gerendert wird.&lt;/P&gt;
&lt;P&gt;Ich hoffe das dieses Beispiel ein wenig Klarheit bringt und vor allem euch aufweckt, Exception Handling mit Bedacht einzusetzen und nicht an einem solch komischen Verhalten zu verzweifeln.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Zusatz / Fazit:&lt;/STRONG&gt;&lt;BR&gt;Wie man sehen kann, ist der Scope (Wirkungsbereich) von Try / Catch um die ganze Page_Load-Methode gelegt.&lt;BR&gt;Dies kann Sinn machen, jedoch nicht in der Mehrzahl der Fälle, wie auch in diesem Fall.&lt;/P&gt;
&lt;P&gt;Meiner Meinung nach, und so steht es auch in den meisten Büchern, &lt;STRONG&gt;sollten&lt;/STRONG&gt; Fehler punktuell &lt;STRONG&gt;abgefangen werden&lt;/STRONG&gt;, nur dort wo man ihn auch behandeln kann und der &lt;STRONG&gt;Scope&lt;/STRONG&gt; sollte möglichst &lt;STRONG&gt;klein gehalten&lt;/STRONG&gt; werden, damit das Problem auch schnell identifiziert ist.&lt;/P&gt;
&lt;P&gt;Die unbehandelten Fehler kann man dann generell in ASP.NET bspw. in der Global.asax.cs in der Methode Application_Error() loggen.&lt;BR&gt;Ich persönlich gehe sogar so vor, das ich zuerst ohne Fehlerbehandlung entwickle und diese erst später hinzufüge.&lt;BR&gt;So gehen während der Entwicklung keine Fehler vergessen und das Programm befindet sich nie in einem inkonsistenten Zustand.&lt;/P&gt;
&lt;P&gt;Solchen Code wie oben gezeigt ist - wie auch &lt;A href="http://webenliven-space.de/dotnetblog/"&gt;Gregor&lt;/A&gt; im Kommentar &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/13/fehler-verstecken-leicht-gemacht.aspx#214591"&gt;bemerkt&amp;nbsp;hat&lt;/A&gt; - vielerorts zu finden, was ich tragisch finde.&lt;BR&gt;Die Konsequenzen daraus müssen in keinem Fall so harmlos sein, wie in diesem Beispiel gezeigt. Man stelle sich nur mal ein Atomkraftwerk vor, das durch eine inkonsistente Software gesteuert wird.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Bearbeitung / Korrekturen&lt;/STRONG&gt;:&lt;BR&gt;13.11.09 - Fehlendes Komma in den Codesnippets hinzugefügt&lt;BR&gt;13.11.09 - Zusatz / Fazit hinzugefügt&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=214589" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="ASP.NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx" /><category term="Artikel" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Artikel/default.aspx" /><category term=".NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/.NET/default.aspx" /><category term="Aua" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Aua/default.aspx" /><category term="TryCatch" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/TryCatch/default.aspx" /><category term="Fehlerbehandlung" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Fehlerbehandlung/default.aspx" /></entry><entry><title>Professionals im Profil - Interview von Golo Roden mit mir</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/06/professionals-im-profil-interview-von-golo-roden-mit-mir.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/06/professionals-im-profil-interview-von-golo-roden-mit-mir.aspx</id><published>2009-11-06T16:58:00Z</published><updated>2009-11-06T16:58:00Z</updated><content type="html">&lt;P&gt;&lt;A href="http://www.goloroden.de/"&gt;Golo Roden&lt;/A&gt; hat mit&amp;nbsp;&lt;A href="http://www.professionals-im-profil.net/"&gt;http://www.professionals-im-profil.net/&lt;/A&gt; ein Projekt gestartet, wo er berufstätige Entwickler interviewt, unter anderem mit der Frage, wie man den Einstieg ins Berufsleben geschafft hat und vorallem woher man die Motivation nimmt, immer neue Dinge zu lernen.&lt;/P&gt;
&lt;DIV class=Quotes&gt;
&lt;P&gt;Softwareentwicklung ist ein faszinierendes Thema – keine Frage. Doch wie gelingt der Einstieg? Wie und womit sollte man beginnen? Woher die Motivation und die Energie nehmen, auf Dauer beständig Neues zu lernen? Welche Voraussetzungen sollte man als Anfänger überhaupt erfüllen, um auf Dauer erfolgreich sein zu können? &lt;/P&gt;
&lt;P&gt;All diese Fragen beschäftigen jene, die heute versuchen, einen vernünftigen Einstieg in die Softwareentwicklung zu finden. &lt;/P&gt;
&lt;P&gt;Doch diese Fragen haben auch all jene beschäftigt, denen der Einstieg bereits gelungen ist und die sich inzwischen professionell – entweder beruflich oder in der Community – mit Softwareentwicklung beschäftigen. &lt;/P&gt;
&lt;P&gt;Warum also nicht einfach fragen, wie es ihnen bei ihrem Einstieg ergangen ist? Welche Hürden sie zu überwindern hatten, welche Erfolgserlebnisse sie hatten, und woher sie ihre Motivation genommen haben? &lt;/P&gt;
&lt;P&gt;Dies ist die Idee von &lt;EM&gt;.NET Professionals im Profil&lt;/EM&gt;: Die Webseite enthält Interviews zu diesem Thema mit Personen, die im Bereich .NET professionell tätig sind und sich beruflich oder in der Community einen Namen gemacht haben.&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Für mich ist es eine Ehre, sich als ersten den Fragen von Golo stellen zu dürfen und ich freue mich schon auf die folgenden Interviews.&lt;BR&gt;Das Interview mit mir ist unter &lt;A href="http://www.professionals-im-profil.net/Peter-Bucher.aspx"&gt;http://www.professionals-im-profil.net/Peter-Bucher.aspx&lt;/A&gt;&amp;nbsp;zu finden.&lt;/P&gt;
&lt;P&gt;Viel Spass!&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=214451" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term=".NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/.NET/default.aspx" /><category term="Professionals" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Professionals/default.aspx" /><category term="Motivation" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Motivation/default.aspx" /><category term="Interview" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Interview/default.aspx" /></entry><entry><title>Wieviel Sinn machen Unittests?</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/01/wieviel-sinn-machen-unittests.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/11/01/wieviel-sinn-machen-unittests.aspx</id><published>2009-11-01T08:37:00Z</published><updated>2009-11-01T08:37:00Z</updated><content type="html">&lt;P&gt;Am 13. Oktober 2008 haben &lt;A href="http://www.des-eisbaeren-blog.de/"&gt;Golo Roden&lt;/A&gt; und ich unter dem Titel &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/10/13/noch-fragen-roden-ja-bucher.aspx"&gt;Noch Fragen, Roden? Ja, Bucher!&lt;/A&gt; angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen.&lt;BR&gt;Außerdem nimmt diesen Monat auch &lt;A href="http://www.hauser-wenz.de/s9y/index.php?/archives/283-Wieviel-Sinn-machen-Unit-Tests.html"&gt;Christian Wenz&lt;/A&gt; wieder an unserem Streitgespräch teil.&lt;/P&gt;
&lt;P&gt;Bisher sind in dieser Reihe folgende Kommentare erschienen: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;1. Oktober 2009: Vererben oder aggregieren?&lt;/EM&gt; 
&lt;LI&gt;1. September 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/01/alles-var-oder-nicht.aspx"&gt;Alles var – oder nicht?&lt;/A&gt; 
&lt;LI&gt;1. August 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/08/01/c-oder-vb-welche-sprache-soll-ich-lernen.aspx"&gt;C# oder VB: Welche Sprache soll ich lernen?&lt;/A&gt; 
&lt;LI&gt;1. Juli 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/07/01/prim-rschl-ssel-guid-vs-identity.aspx"&gt;Primärschlüssel: GUID vs Identity&lt;/A&gt; 
&lt;LI&gt;1. Juni 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/06/01/heisst-die-zukunft-ria.aspx"&gt;Heißt die Zukunft RIA?&lt;/A&gt; 
&lt;LI&gt;1. Mai 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/05/01/woran-erkennt-man-einen-guten-entwickler.aspx"&gt;Woran erkennt man einen guten Entwickler?&lt;/A&gt; 
&lt;LI&gt;1. April 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/04/01/interfaces-vs-abstrakte-klassen.aspx"&gt;Interfaces vs abstrakte Klassen&lt;/A&gt; 
&lt;LI&gt;1. März 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/03/01/sinn-und-zweck-von-aop.aspx"&gt;Sinn und Zweck von AOP&lt;/A&gt; 
&lt;LI&gt;1. Februar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/02/01/die-forderung-nach-softwarequalit-t.aspx"&gt;Die Forderung nach Softwarequalität&lt;/A&gt; 
&lt;LI&gt;1. Januar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/01/01/soa-vs-woa.aspx"&gt;SOA vs WOA&lt;/A&gt; 
&lt;LI&gt;1. Dezember 2008: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/12/01/dynamic-language-runtime-net-quo-vadis.aspx"&gt;Dynamic Language Runtime: .NET, quo vadis?&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Heute, am 1.&amp;nbsp;November 2009, ist es nun wieder so weit, und unser Thema für diesen Monat lautet: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;Wieviel Sinn machen Unittests?&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So wohl Golo wie auch ich haben uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen. &lt;A href="http://www.des-eisbaeren-blog.de/post/2009/11/01/Wie-viel-Sinn-machen-Unittests.aspx"&gt;Golos Kommentar&lt;/A&gt; findet sich zeitgleich in seinem Blog, folgend nun mein Kommentar zu diesem Thema:&lt;/P&gt;
&lt;P&gt;Schon in einem früheren Streitgespräch “&lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/02/01/die-forderung-nach-softwarequalit-t.aspx"&gt;Die Forderung nach Softwarequalität&lt;/A&gt;” habe ich Unittests erwähnt.&lt;/P&gt;
&lt;P&gt;Ich würde als direkte Antwort natürlich gleich sagen: Sehr viel Sinn! &lt;BR&gt;Jedoch muss die Frage irgendwie auseinandergenommen werden, denn generell lässt sie sich nicht beantworten.&lt;/P&gt;
&lt;P&gt;Wo macht Unittesting Sinn?&lt;/P&gt;
&lt;P&gt;Grundsätzlich macht es überall Sinn, wo das Verfahren leicht anzuwenden ist, ohne irgendwelche Handstände zu machen. &lt;/P&gt;
&lt;P&gt;&lt;U&gt;Schwierige Testumgebungen&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Gerade in der Webentwicklung bzw. überall wo eine Oberfläche vorhanden ist, wird es schwieriger Abläufe zu testen.&lt;/P&gt;
&lt;P&gt;Handelsübliche ASP.NET (WebForms) Anwendungen die schon entwickelt sind, jedoch nachträglich getestet werden müssen, eigenen sich überhaupt nicht dazu, nachträglich mit Unittesting zu versorgt zu werden. &lt;BR&gt;Das liegt daran dass die Zuständigkeiten (Concerns) physikalisch und auch logisch nicht strikt getrennt sind, sondern schlussendlich bei den meisten Anwendungen irgendwo in den Page-Eventhandlern liegt.&lt;/P&gt;
&lt;P&gt;Zum “nachträglich” kommen wir dann später noch mal zurück.&lt;/P&gt;
&lt;P&gt;Wenn eine ASP.NET Anwendung von Grund auf neu entwickelt wird, kann das MVP (&lt;A href="http://de.wikipedia.org/wiki/Model_View_Presenter"&gt;Model View Presenter&lt;/A&gt;)-Pattern eingesetzt werden, damit Unittests überhaupt eingesetzt werden können. &lt;BR&gt;Wiederum gibt es ASP.NET MVC, das – wie der Name schon sagt – auf das MVC (&lt;A href="http://de.wikipedia.org/wiki/Model_View_Controller"&gt;Model View Controller&lt;/A&gt;)-Pattern setzt, was die Testbarkeit um einiges vereinfacht. &lt;BR&gt;Natürlich gibt es auch dort noch Hürden und auch eine ASP.NET MVC Anwendung kann so geschrieben werden, das sie kaum noch testbar ist.&lt;/P&gt;
&lt;P&gt;Für solche schwer testbare Anwendungen sind Oberflächentests der bessere bzw. möglichere Weg und stellen auch einen zusätzlichen Weg dar, für Anwendungen die schon mit Unittests abgedeckt sind.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Optimale Testumgebungen&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Am besten eigenen sich kleine Greenfield (Start von der grünen Wiese aus)-Projekte, die – wenn möglich – Bibliotheken sind, die dann später in die Oberfläche integriert werden, bzw. ihre Aufgabe aufgrund einer Aktion der Oberfläche erfüllen.&lt;/P&gt;
&lt;P&gt;Ein super Beispiel dafür ist die Entwicklung eines &lt;A href="http://de.wikipedia.org/wiki/Dependency_Injection"&gt;Dependency Injection Containers&lt;/A&gt;. Da kann man sogar hergehen und komplett testgetrieben arbeiten, also zuerst den Test und dann der Produktivcode, weil keine äusseren Abhängigkeit oder Oberflächen mit von der Partie sind. &lt;BR&gt;Schlussendlich kann dann so sichergestellt werden, dass der Code das tut, was er sollte, zumindest in den getesteten Szenarien.&lt;/P&gt;
&lt;P&gt;Lizenznummern generieren, parsen, zählen, prüfen, auch das ist ein super Beispiel wo Unittesting sehr gut angewendet werden kann, wenn es richtig aufgezogen wird. &lt;BR&gt;Ich würde sogar behaupten es wäre fast unmöglich ohne irgendwelche Tests (Und hier eigenen sich Unittests am besten), so eine Bibliothek aufzubauen und sicherzustellen, damit sie korrekt funktioniert.&lt;/P&gt;
&lt;P&gt;Denn erstens kann so sichergestellt werden, dass sich das implementierte Verhalten auch so verhält, wie es der Test vorschreibt und zweitens können Seiteneffekte entdeckt, behoben und schlussendlich ausgeschlossen werden. Denn nach jedem zusätzlich geschriebenen Test, sollten alle Tests noch einmal durchlaufen, so können dann Seiteneffekte erkannt und behoben werden.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Wieviel Testabdeckung ist sinnvoll?&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Vielerorts wird geschrieben und gesagt das 100% Testabdeckung das Ziel sein sollte. Ich sage, das es gut ist, seine Ziele hochzustecken. Jedoch sind eben die letzten paar Prozent fast nicht testbar, oder es macht keinen Sinn sie zu testen, entweder weil es viel zu aufwändig ist, oder der Code schon durch Integrationstests abgedeckt ist. &lt;/P&gt;
&lt;P&gt;&lt;U&gt;Nachträgliches Unittesting?&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Eine Anwendung nachträglich mit Unittests abzudecken macht m.E. nicht sehr viel Sinn. &lt;BR&gt;Es gibt zuviel Aufwand und die Anwendung bzw. dessen Abläufe und verstrickter Code soll bestimmen, wie / wo und was getestet werden soll / muss. &lt;BR&gt;Ich habe das Gefühl, dass sowas sehr schwierig ist, im nachhinein reinzupflanzen, nicht nur wegen dem Aufwand, sondern auch weil man nicht wirklich weiss, was getestet werden soll und wann alles abgedeckt ist.&lt;/P&gt;
&lt;P&gt;Anders sieht es bei einem Redesign einer Anwendung aus, dort kann man eher Unittests einbauen, ganz sicher beim neuen Code und dann ggf. noch die Integration mit dem bestehenden Code testen, der dann meistens dabei noch angepasst wird.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Hardcore-TDD?&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;“Hardcore-TDD”, also zuerst die Tests und erst danach den Produktivcode, oder eher locker mal den Code schreiben und am Schluss die Tests hinzufügen?&lt;/P&gt;
&lt;P&gt;Ja, ich gebe es zu, das ist eine Streitfrage. Ehrlich gesagt verstehe ich aber nicht wieso :-). &lt;BR&gt;Irgendwie habe ich das Gefühl das es Extreme gibt, um den Menschen überhaupt klar zu machen, das es so / oder dies und das besser ist, als das bisherige. &lt;BR&gt;Mit dieser Vorgehensweise kann man die Leute zum Aufwachen bringen, sich das überhaupt mal anzusehen – auch bei &lt;A href="http://cleancodedeveloper.de/"&gt;Clean Code Developer&lt;/A&gt; / Clean Code schön zu sehen.&lt;/P&gt;
&lt;P&gt;Wenn man vor den Kopf gestossen wird, ist das schon mal der erste Schritt. Der zweite Schritt ist dann, sich mit dem Extremen zu befassen und irgendwo seinen Stil einzuordnen. Ich finde es macht – abgesehen um Leute vor den Kopf zu stossen – überhaupt keinen Sinn, etwas ins Extreme zu treiben.&lt;/P&gt;
&lt;P&gt;Immer zuerst den Test schreiben und erst dann den Produktivcode mag bei kleineren Projekten, oder eben solchen die sehr modular und für Tests optimiert aufgebaut sind, funktionieren.&lt;/P&gt;
&lt;P&gt;Ich habe das selber auch schon probiert und es ist schon eine coole Erfahrung:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Test schreiben 
&lt;LI&gt;Benötigte Klassen erstellen 
&lt;LI&gt;Kompilieren =&amp;gt; kompiliert 
&lt;LI&gt;Test laufen lassen =&amp;gt; schlägt fehl =&amp;gt; &lt;FONT color=#ff0000&gt;rot&lt;/FONT&gt; 
&lt;LI&gt;Klassen ausimplementieren, nur das nötigste 
&lt;LI&gt;Test laufen lassen =&amp;gt; läuft =&amp;gt; &lt;FONT color=#008000&gt;grün&lt;/FONT&gt; &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Es gäbe theoretisch noch einen Zwischenschritt, bei dem kompiliert wird, obwohl die Klassen noch nicht vorhanden sind, aber damit kann ich mich irgendwie nicht anfreunden. &lt;BR&gt;Auf jeden Fall macht man sich damit Gedanken, wie man sein API benutzen möchte und modeliert dann die Klassen auch so aus, &lt;BR&gt;zusätzlich wird im besten Fall nur das implementiert was die Tests erwarten, also bis sie grün sind.&lt;/P&gt;
&lt;P&gt;So kann mit Leichtigkeit die Einhaltung von &lt;A href="http://de.wikipedia.org/wiki/YAGNI"&gt;YAGNI&lt;/A&gt; beim Entwickeln eingehalten werden.&lt;/P&gt;
&lt;P&gt;Meiner Erfahrung ist aber leider die, dass vielerorts eben schon Projekte bestehen, die nicht darauf optimiert sind, mit Unittests abgedeckt zu werden. &lt;BR&gt;Sei das jetzt nachträglich oder für neue Features die dazukommen. Dort ist es echt schwierig und da können meistens nur sehr loose angedockte Zusatzbibliotheken getestet werden, also ein Greenfield-Projekt das dann in die bestehende Umgebung eingebunden wird.&lt;/P&gt;
&lt;P&gt;Überall wo es möglich ist, nach TDD zu entwickeln, mache ich das jetzt auch – mehr oder weniger, aber nicht komplett im Extremen.&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=214307" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="Streitgespr&amp;#228;ch" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Streitgespr_26002300_228_3B00_ch/default.aspx" /><category term="UnitTesting" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/UnitTesting/default.aspx" /><category term="TDD" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/TDD/default.aspx" /></entry><entry><title>Richtig testen, oder: Was ist schneller… Foreach, LAMBDA Expressions, oder LINQ?</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/09/richtig-testen-oder-was-ist-schneller-foreach-lambda-expressions-oder-linq.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/09/richtig-testen-oder-was-ist-schneller-foreach-lambda-expressions-oder-linq.aspx</id><published>2009-09-09T21:43:00Z</published><updated>2009-09-09T21:43:00Z</updated><content type="html">&lt;P&gt;&lt;STRONG&gt;Einleitung&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Der schweizer Kollege &lt;A href="http://xtreme-schaedler.spaces.live.com/"&gt;Daniel Schädler&lt;/A&gt; hat einen Blogpost mit dem Titel “Was ist schneller… Foreach, LAMBDA Expressions, oder LINQ?” &lt;A href="http://xtreme-schaedler.spaces.live.com/blog/cns!CE67B0BB158A026D!2375.entry?wa=wsignin1.0&amp;amp;sa=461754336"&gt;veröffentlicht&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Nur schnell eine Korrektur zum Titel, die LINQ-Syntax wird – &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/06/08/optimierungseinstellung-im-reflector-oder-wie-sieht-linq-wirklich-aus.aspx"&gt;wie hier schon gezeigt&lt;/A&gt; – schlussendlich in die Erweiterungsmethoden-Syntax kompiliert. &lt;BR&gt;Ich habe den Titel so übernommen, damit klar ist, dass das eine Antwort auf seinen Post darstellt.&lt;/P&gt;
&lt;P&gt;Daniel hat sich die Frage gestellt, was wohl schneller ist: Listen per foreach, über LINQ oder die Erweiterungsmethoden Syntax für LINQ filtern.&lt;/P&gt;
&lt;P&gt;Nun, ich wusste natürlich schon vorher, dass die Resultate nur ganz wenig auseinander liegen dürfen, weil:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Wird die LINQ-Syntax in den Erweiterungsmethoden-Syntax übersetzt (Nahezu gleich). 
&lt;LI&gt;Arbeitet LINQ intern auch mit den Iteratoren, wie sie in foreach genutzt werden. Siehe &lt;A href="http://msdn.microsoft.com/de-de/library/system.linq.enumerable.aspx"&gt;Enumerable-Klasse&lt;/A&gt; im &lt;A href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/A&gt;. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Abgesehen davon nutze ich diese Antwort in Form eines Blogposts einfach mal dazu, wie ich Geschwindigkeiten teste, auch wenn es in diesem Fall für mich theoretisch klar war, das alle in etwa gleich schnell sind. &lt;BR&gt;Es braucht für einen Geschwindigkeitstest nicht unbedingt eine grafische Anwendung, auch wenn das natürlich nicht schlecht ist. Ich habe mir den Aufwand nicht gemacht und mich auf das Wesentliche konzentriert: Das Testen.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Verfälschte Tests und wie sie verhindert werden können&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Der Test von Daniel liefert leider das falsche Resultat, sogar ein sehr verfälschtes. &lt;BR&gt;Das liegt daran, das die Ergebnisse von LINQ bzw. den Erweiterungsmethoden als IEnumerable&amp;lt;T&amp;gt; zurückgegeben werden und diese zeitverzögert ausgeführt werden (deferred Execution).&lt;/P&gt;
&lt;P&gt;Das heisst der ganze Code der die IEnumerable&amp;lt;T&amp;gt; Instanz liefert, &lt;U&gt;wird erst ausgeführt, wenn das Ergebnis tatsächlich durchlaufen wird&lt;/U&gt;. &lt;BR&gt;Dies kann bspw. mit &amp;lt;Menge&amp;gt;.Count(), &amp;lt;Menge&amp;gt;.ToList(), … angestossen werden.&lt;/P&gt;
&lt;P&gt;Erst dann, und wirklich erst dann wird der Code überhaupt ausgeführt und braucht dann eben auch länger.&lt;/P&gt;
&lt;P&gt;Auch wenn dies geschehen ist, bleibt das Ergebnis von Daniel noch verfälscht, denn eine Testiteration kann durch mehrere Faktoren verfälscht werden. &lt;BR&gt;Sei das eine einmalige Kompilation einer Abfrage zur Laufzeit oder durch diversen Hintergrundprozessen die genau in dem Moment mehr Leistung benötigen als beim vorherigen Testkandidaten.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;Es heisst also: Mehrere Iterationen einer Operation die getestet werden will, ausführen.&lt;/U&gt;&lt;/P&gt;
&lt;P&gt;Darüber hinaus ist es noch so, dass das Gesamtergebnis auch noch bei mehreren Iterationen der zu testenden Operation verfälscht sein kann, weil eben die erste ausgeführte Operation verfälscht ist.&lt;/P&gt;
&lt;P&gt;Um da einen Mittelwert zu bekommen, macht man über die ganzen Testläufe &lt;U&gt;nochmals&lt;/U&gt; mehrere Testläufe. &lt;BR&gt;Das hört sich jetzt womöglich ein bisschen verwirrend an, jedoch meine ich einfach gesagt nur folgendes:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Eine Operation: Einträge aus einer Menge filtern 
&lt;LI&gt;Mehrere Iterationen einer Operation: Die Operationen mehrmals ausführen 
&lt;LI&gt;Das ganze für alle Testkandidaten mehrmals ausführen &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Somit kann man sehr sicher sein, dass die Ergebnisse der verschiedenen Kandidaten realistisch miteinander vergleichbar sind, nicht aber dass die Werte 1:1 dem entsprechen, wie sie dann auch in der Produktivumgebung auftreten, denn dort kommen wieder andere Faktoren dazu.&lt;/P&gt;
&lt;P&gt;Nur das keine Missverständisse auftreten: Natürlich ist dann ein solcher Test auch für die Praxis aussagekräftig, nur wird er nicht 100% gleich ausfallen, wenn man die Zeit stoppt.&lt;/P&gt;
&lt;P&gt;Als Testhilfe würde ich nicht &lt;EM&gt;DateTime.Now&lt;/EM&gt;, etc.. benutzen, da dies zu ungenau ist. Das meines Wissens genauste Instrument das ohne &lt;A href="http://www.pinvoke.net/"&gt;P/Invoke-Aufrufe&lt;/A&gt; in unmanaged Code verfügbar ist, heisst &lt;A href="http://msdn.microsoft.com/de-de/library/system.diagnostics.stopwatch.aspx"&gt;Stopwatch&lt;/A&gt; und ist im System.Diagnostics-Namespace zu finden.&lt;/P&gt;
&lt;DIV class=Quotes&gt;Mittels P/Invoke Aufrufen lässt sich eine &lt;STRONG&gt;noch genauere Messung&lt;/STRONG&gt; vornehmen, jedoch ist das dann vorallem für Echtzeitanwendungen sinnvoll. Den Einsatz sieht man in einem &lt;A href="http://www.mycsharp.de/wbb2/thread.php?postid=166739#post166739"&gt;myCSharp-Post für einen Framecounters unter XNA&lt;/A&gt;. &lt;/DIV&gt;
&lt;P&gt;Mittels der Eigenschaft &lt;A href="http://msdn.microsoft.com/de-de/library/system.diagnostics.stopwatch.elapsedmilliseconds.aspx"&gt;&amp;lt;Stopwatch&amp;gt;.ElapsedMilliseconds&lt;/A&gt; lassen sich die Millisekunden auslesen, die seit dem Start- und Stopaufruf vergangen sind, das reicht uns für den Test und ist auch aussagekräftig und vorstellbar, was bei den von Daniel genutzten Ticks m.E. nicht der Fall ist.&lt;/P&gt;
&lt;P&gt;Für die Tests nutze ich eine Methode namens SpeedTest die einen &lt;A href="http://www.mycsharp.de/wbb2/thread.php?threadid=74181"&gt;Action-Delegate&lt;/A&gt; entgegennimmt den sie n-Mal ausführt. &lt;BR&gt;So kann das Testen zentralisiert werden und ist mit sehr kleinem Aufwand möglich den Test selber zu erweitern, sowie neue Kandidaten hinzuzufügen.&lt;/P&gt;
&lt;P&gt;Wenn der Test ausgeführt wird, habe ich Abweichungen von &lt;STRONG&gt;1 bis 4 Millisekunden&lt;/STRONG&gt; und das bei sehr vielen Durchläufen. Diese Abweichungen sind für mich also – wie am Anfang vermutet – &lt;STRONG&gt;irrelevant&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Folgend den Code der ich für meinen Test verwendet habe:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;using&lt;/span&gt; System; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;using&lt;/span&gt; System.Collections.Generic; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;using&lt;/span&gt; System.Diagnostics; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;using&lt;/span&gt; System.Linq; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;namespace&lt;/span&gt; SpeedTest &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; Program &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Main(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;[] args) &lt;br /&gt;        { &lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; randomDataCount &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 1000; &lt;br /&gt;            var persons &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; GetPersons(randomDataCount); &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; iterations &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 1000; &lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; runs &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 10; &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;for&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; runNumber &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 1; runNumber &amp;lt;= runs; runNumber++) &lt;br /&gt;            { &lt;br /&gt;                Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Run {0} ---------------"&lt;/span&gt;, runNumber); &lt;br /&gt;&lt;br /&gt;                SpeedTest(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"LINQ"&lt;/span&gt;, iterations, &lt;br /&gt;                          () =&amp;gt; &lt;br /&gt;                          { &lt;br /&gt;                              var result &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; (from person &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; persons &lt;br /&gt;                                            where person.FirstName.Equals(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Peter"&lt;/span&gt;) &amp;amp;&amp;amp; person.Age &amp;lt;= 25 &lt;br /&gt;                                            select person).ToList(); &lt;br /&gt;                          }); &lt;br /&gt;&lt;br /&gt;                SpeedTest(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"LINQ Extension Syntax"&lt;/span&gt;, iterations, &lt;br /&gt;                          () =&amp;gt; &lt;br /&gt;                          { &lt;br /&gt;                              var result &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; persons.Where(p =&amp;gt; p.FirstName.Equals(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Peter"&lt;/span&gt;) &amp;amp;&amp;amp; p.Age &amp;lt;= 25).ToList(); &lt;br /&gt;                          }); &lt;br /&gt;&lt;br /&gt;                SpeedTest(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Manual ForEach"&lt;/span&gt;, iterations, &lt;br /&gt;                          () =&amp;gt; &lt;br /&gt;                          { &lt;br /&gt;                              List&amp;lt;Person&amp;gt; result &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; List&amp;lt;Person&amp;gt;(); &lt;br /&gt;&lt;br /&gt;                              &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;foreach&lt;/span&gt; (Person person &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; persons) &lt;br /&gt;                              { &lt;br /&gt;                                  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt; (person.FirstName.Equals(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Peter"&lt;/span&gt;) &amp;amp;&amp;amp; person.Age &amp;lt;= 25) &lt;br /&gt;                                  { &lt;br /&gt;                                      result.Add(person); &lt;br /&gt;                                  } &lt;br /&gt;                              } &lt;br /&gt;                          }); &lt;br /&gt;&lt;br /&gt;                Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"End run --------"&lt;/span&gt;); &lt;br /&gt;                Console.WriteLine(String.Empty); &lt;br /&gt;            } &lt;br /&gt;&lt;br /&gt;            Console.Read(); &lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; SpeedTest(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; description, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; iterations, Action speedTestAction) &lt;br /&gt;        { &lt;br /&gt;            Stopwatch watch &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Stopwatch(); &lt;br /&gt;            watch.Start(); &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;for&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; i &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 0; i &amp;lt; iterations; i++) &lt;br /&gt;            { &lt;br /&gt;                speedTestAction(); &lt;br /&gt;            } &lt;br /&gt;&lt;br /&gt;            watch.Stop(); &lt;br /&gt;&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"{0}: {1}ms"&lt;/span&gt;, &lt;br /&gt;                              description, &lt;br /&gt;                              watch.ElapsedMilliseconds); &lt;br /&gt;&lt;br /&gt;            Console.WriteLine(String.Empty); &lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; IEnumerable&amp;lt;Person&amp;gt; GetPersons(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; randomDataCount) &lt;br /&gt;        { &lt;br /&gt;            Random random &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Random(); &lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;[] surnames &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt;[] { &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Peter"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Daniel"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Johannes"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Stefanie"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Hans"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Klaus"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Benjamin"&lt;/span&gt; }; &lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;[] lastnames &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt;[] { &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Bucher"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Hurzeler"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Kübel"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Honegger"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Bock"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Wurst"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Grube"&lt;/span&gt; }; &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; dataLength &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; surnames.Length; &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;for&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; i &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; 0; i &amp;lt; randomDataCount; i++) &lt;br /&gt;            { &lt;br /&gt;                yield &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Person &lt;br /&gt;                                 { &lt;br /&gt;                                     FirstName &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; surnames[random.Next(0, dataLength)], &lt;br /&gt;                                     LastName &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; lastnames[random.Next(0, dataLength)], &lt;br /&gt;                                     Age &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; random.Next(0, 100) &lt;br /&gt;                                 }; &lt;br /&gt;            } &lt;br /&gt;        } &lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; Person &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; FirstName { get; set; } &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; LastName { get; set; } &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; Age { get; set; } &lt;br /&gt;    } &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=212925" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term=".NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/.NET/default.aspx" /><category term="XNA" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/XNA/default.aspx" /><category term="Testen" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Testen/default.aspx" /><category term="Lambda" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Lambda/default.aspx" /><category term="LINQ" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/LINQ/default.aspx" /><category term="PInvoke" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/PInvoke/default.aspx" /><category term="Speed" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Speed/default.aspx" /><category term="Geschwindigkeit" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Geschwindigkeit/default.aspx" /></entry><entry><title>Generierung der designer.cs / vb Datei forcieren oder “Der Name ControlXYZ ist im aktuellen Kontext nicht vorhanden</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/03/generierung-der-designer-cs-vb-datei-forcieren-oder-der-name-controlxyz-ist-im-aktuellen-kontext-nicht-vorhanden.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/03/generierung-der-designer-cs-vb-datei-forcieren-oder-der-name-controlxyz-ist-im-aktuellen-kontext-nicht-vorhanden.aspx</id><published>2009-09-03T17:34:00Z</published><updated>2009-09-03T17:34:00Z</updated><content type="html">&lt;P&gt;Wenn eine ASPX- / ASCX-Datei ausserhalb vom Visual Studio Editor geändert wird, bekommt das der Designer nicht mit. &lt;BR&gt;Das Updaten der &amp;lt;Dateiname&amp;gt;.&amp;lt;Erweiterung&amp;gt;.designer.cs geschieht nicht sehr häufig und nur bei bestimmten Fällen.&lt;/P&gt;
&lt;P&gt;So kann es gut sehr gut sein, dass folgende Fehlermeldung beim Kompilieren erscheint:&lt;/P&gt;
&lt;DIV class=Error&gt;The name ‘ControlXYZ’ does not exists in the current context&lt;/DIV&gt;
&lt;P&gt;bzw.&lt;/P&gt;
&lt;DIV class=Error&gt;Der Name ControlXYZ ist im aktuellen Kontext nicht vorhanden&lt;/DIV&gt;
&lt;P&gt;Um die &lt;STRONG&gt;Neugenerierung&lt;/STRONG&gt; der Designer-Datei &lt;STRONG&gt;zu erzwingen&lt;/STRONG&gt;, kann die ASPX- / ASCX- Datei im Designer geöffnet werden, oder eine Eigenschaft hinzugefügt / geändert werden.&lt;/P&gt;
&lt;P&gt;Wenn das nichts nützt (Danke an &lt;A href="http://www.aspnetzone.de/blogs/stefanfalz/"&gt;Stefan&lt;/A&gt;):&lt;/P&gt;
&lt;DIV class=Quotes&gt;
&lt;P&gt;Leider funktioniert das aber lange nicht immer. Ich hab das gerade bei größeren Projekten (meist dann, wenn man in VS ein Control kopiert und umbenennt (inkl. Klassenname natürlich) öfter mal. Schon ein paar mal half schlußendlich nur das Löschen der Datei in VS und das erneute Erstellen. Reines Drag&amp;amp;Drop in das VS Projekt hinein half da auch nciht.&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Mehr Details zu diesem Verhalten gibt es in folgendem Posting:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://social.msdn.microsoft.com/Forums/en-US/csharpide/thread/128202d7-5ecb-4921-8ac3-e173d4824235"&gt;Forcing regeneration of the designer.cs file&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=212767" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="ASP.NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx" /><category term="Tipps" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Tipps/default.aspx" /><category term="Fehler" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Fehler/default.aspx" /><category term="Generierung" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Generierung/default.aspx" /><category term="designer.cs" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/designer_2E00_cs/default.aspx" /><category term="Designer" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Designer/default.aspx" /></entry><entry><title>LINQ: Any, anyone? Range oder Repeat?</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/01/linq-any-anyone-range-oder-repeat.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/01/linq-any-anyone-range-oder-repeat.aspx</id><published>2009-09-01T16:10:00Z</published><updated>2009-09-01T16:10:00Z</updated><content type="html">&lt;P&gt;Mit &lt;A href="http://de.wikipedia.org/wiki/LINQ"&gt;LINQ&lt;/A&gt; sind unzählige Erweiterungsmethoden für &lt;A href="http://msdn.microsoft.com/de-de/library/9eekhta0.aspx"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/A&gt; hinzugekommen, die auch ausserhalb von LINQ Abfragen sehr nützlich sein können.&lt;/P&gt;
&lt;P&gt;Damit ich mir das merke und ihr evt. noch was neues kennenlernt, möchte ich zwei kurz vorstellen:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;A href="http://msdn.microsoft.com/de-de/library/system.linq.enumerable.any.aspx"&gt;Enumerable.Any()&lt;/A&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Kommt euch Code wie der folgende bekannt vor?&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(addresses.Count &amp;gt; 0) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// … &lt;/span&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;oder&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(addresses.Count == 0) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// … &lt;/span&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Das kann jetzt folgendermassen umgeschrieben werden:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(addresses.Any()) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// … &lt;/span&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;und&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(!addresses.Any()) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// … &lt;/span&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Die Implementation der Any()-Methode holt sich den Enumerator der Auflistung und versucht den ersten Eintrag zu holen, wenn das klappt gibt sie true zurück, ansonsten false.&lt;/P&gt;
&lt;P&gt;Wenn Any() true zurückliefert, heisst das also, es ist mindestens ein Element vorhanden.&lt;/P&gt;
&lt;P&gt;PS: Darüber hinaus gibt es auch noch eine &lt;A href="http://msdn.microsoft.com/en-us/library/bb534972.aspx"&gt;zweite Überladung&lt;/A&gt;, der man Funktion einspeisen kann (Anonyme Methode, Lambda Ausdruck, …). Diese bestimmt dann, ob es mindestens ein Element hat, bei dem die Funktion true zurückliefert. &lt;BR&gt;Die Funktion nimmt ein Element vom Typ TSource entgegen und gibt einen bool zurück.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.range.aspx"&gt;Enumerable.Range()&lt;/A&gt; und &lt;STRONG&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/bb348899.aspx"&gt;Enumerable.Repeat()&lt;/A&gt;&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Schon mal Testdaten benötigt, oder eine Liste von Zahlen die dann durcheinandergewürfelt werden? &lt;BR&gt;Das schreibt man im einfachsten Fall dann in etwa so:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;List&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt; numbers &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;(); &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;for&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; i=1; i &amp;lt;= 100; i++) &lt;br /&gt;{ &lt;br /&gt;    numbers.Add(i); &lt;br /&gt;} &lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// …&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Mit Enumerable.Range() geht das viel einfacher:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;var numbers &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Enumerable.Range(1, 100);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// …&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Mit LINQ lässt sich ganz einfach eine gemischte Liste von Zahlen erstellen, zwei Zeilen braucht es dazu:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Random random &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Random(); &lt;br /&gt;var numbers &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Enumerable.Range(1, 100).OrderBy&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;, &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;(random.Next);&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Hier noch ein kleiner Hinweis: Um eine gleichmässige Verteilung einer solchen Liste zu erhalten, sollte ein Algorithmus wie bspw. &lt;A href="http://www.mycsharp.de/wbb2/thread.php?postid=198217#post198217"&gt;hier&lt;/A&gt; benutzt werden.&lt;/P&gt;
&lt;P&gt;An Enumerable.Repeat() hingegen kann im ersten Parameter eine Instanz übergeben werden, oder auch ein einfacher Wertetyp wie bspw. eine Zahl und eine Anzahl, wie häufig dieser Wert wiederholt werden soll. &lt;BR&gt;Schlussendlich bekommt man eine Auflistung zurück, das wars.&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=212663" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="Tipps" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Tipps/default.aspx" /><category term="LINQ" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/LINQ/default.aspx" /><category term="Range" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Range/default.aspx" /><category term="Repeat" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Repeat/default.aspx" /><category term="Random" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Random/default.aspx" /><category term="Shuffle" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Shuffle/default.aspx" /><category term="Any" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Any/default.aspx" /></entry><entry><title>Alles var – oder nicht?</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/01/alles-var-oder-nicht.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/09/01/alles-var-oder-nicht.aspx</id><published>2009-09-01T07:37:00Z</published><updated>2009-09-01T07:37:00Z</updated><content type="html">&lt;P&gt;Am 13. Oktober 2008 haben &lt;A href="http://www.des-eisbaeren-blog.de/"&gt;Golo Roden&lt;/A&gt; und ich unter dem Titel &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/10/13/noch-fragen-roden-ja-bucher.aspx"&gt;Noch Fragen, Roden? Ja, Bucher!&lt;/A&gt; angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen. Bisher sind in dieser Reihe folgende Kommentare erschienen: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;1. August 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/08/01/c-oder-vb-welche-sprache-soll-ich-lernen.aspx"&gt;C# oder VB: Welche Sprache soll ich lernen?&lt;/A&gt; 
&lt;LI&gt;1. Juli 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/07/01/prim-rschl-ssel-guid-vs-identity.aspx"&gt;Primärschlüssel: GUID vs Identity&lt;/A&gt; 
&lt;LI&gt;1. Juni 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/06/01/heisst-die-zukunft-ria.aspx"&gt;Heißt die Zukunft RIA?&lt;/A&gt; 
&lt;LI&gt;1. Mai 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/05/01/woran-erkennt-man-einen-guten-entwickler.aspx"&gt;Woran erkennt man einen guten Entwickler?&lt;/A&gt; 
&lt;LI&gt;1. April 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/04/01/interfaces-vs-abstrakte-klassen.aspx"&gt;Interfaces vs abstrakte Klassen&lt;/A&gt; 
&lt;LI&gt;1. März 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/03/01/sinn-und-zweck-von-aop.aspx"&gt;Sinn und Zweck von AOP&lt;/A&gt; 
&lt;LI&gt;1. Februar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/02/01/die-forderung-nach-softwarequalit-t.aspx"&gt;Die Forderung nach Softwarequalität&lt;/A&gt; 
&lt;LI&gt;1. Januar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/01/01/soa-vs-woa.aspx"&gt;SOA vs WOA&lt;/A&gt; 
&lt;LI&gt;1. Dezember 2008: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/12/01/dynamic-language-runtime-net-quo-vadis.aspx"&gt;Dynamic Language Runtime: .NET, quo vadis?&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Heute, am 1. September 2009, ist es nun wieder so weit, und unser Thema für diesen Monat lautet: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;Alles var – oder nicht?&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So wohl Golo wie auch ich haben uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen. &lt;A href="http://www.des-eisbaeren-blog.de/post/2009/09/01/Alles-var-e28093-oder-nicht.aspx"&gt;Golos Kommentar&lt;/A&gt; findet sich zeitgleich in seinem Blog, folgend nun mein Kommentar zu diesem Thema:&lt;/P&gt;
&lt;P&gt;Nein, werter Leser, das ist &lt;EM&gt;kein&lt;/EM&gt; Rechtschreibefehler, das ist eine wirklich &lt;STRIKE&gt;v&lt;/STRIKE&gt;wa(h)re Geschichte. &lt;BR&gt;Scherz beiseite, los gehts… ;-)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Einleitung&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Mit C# 3.0 kam ein neues Schlüsselwort names &lt;A href="http://msdn.microsoft.com/de-de/library/bb383973.aspx"&gt;var&lt;/A&gt; hinzu, nur was hat es damit auf sich?&lt;/P&gt;
&lt;P&gt;Es handelt sich dabei weder um ein spät gebundenen noch um einen Variant Typ, wie man ihn bspw. von Scriptsprachen her kennt, sondern um ein Feature das erst die Nutzung von anonymen Typen möglich macht.&lt;/P&gt;
&lt;P&gt;Einfach gesagt heisst das, dass der Compiler den Typ auf der linken Seite vom Ausdruck auf der rechten Seite ableitet. &lt;BR&gt;Also sind die Variablen immer stark typisiert und zwar zur Kompilezeit, nicht erst zur Laufzeit.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Was ist der Sinn des ganzen, bzw. wieso wurde dieses Feature integriert?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Im Zuge der Entwicklung von LINQ wurden die anonymen Typen eingefügt um eine Projektion der Daten auf irgendeine Objektstruktur zu ermöglichen, ohne dazu immer wieder neue Datenhaltungsklassen erstellen zu müssen.&lt;/P&gt;
&lt;P&gt;Damit ist dann bspw. sowas möglich:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;List&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;&amp;gt; data &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;&amp;gt; &lt;br /&gt;{ &lt;br /&gt;  &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Patrick:24"&lt;/span&gt;, &lt;br /&gt;  &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Stefan:16"&lt;/span&gt;, &lt;br /&gt;  &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Jörg:22"&lt;/span&gt; &lt;br /&gt;}; &lt;br /&gt;&lt;br /&gt;var persons &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; from dataEntry &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; data &lt;br /&gt;              let splitted &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; dataEntry.Split(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt;[] { ':' }) &lt;br /&gt;              select &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; &lt;br /&gt;              { &lt;br /&gt;                Name &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; splitted[0], &lt;br /&gt;                Age &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt;.Parse(splitted[1]) &lt;br /&gt;              }; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;foreach&lt;/span&gt; (var person &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; persons) &lt;br /&gt;{ &lt;br /&gt;  Console.WriteLine(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Name: {0}, Age: {1}"&lt;/span&gt;, person.Name, person.Age); &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Dabei ist der Typ von &lt;EM&gt;persons&lt;/EM&gt; &lt;A href="http://msdn.microsoft.com/de-de/library/9eekhta0.aspx"&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/A&gt; wobei T in Visual Studio als "a” für Anonymous gekennzeichnet wird. &lt;BR&gt;Und dementsprechend ist jeder Eintrag in dieser durchlaufbaren Menge ein anonymer Typ, der im Hintergrund vom Kompiler generiert und bereitgestellt wird.&lt;/P&gt;
&lt;P&gt;Die Eigenschaft “Name” ist – wer hätte es gedacht – vom Typ string und “Age” vom Datentyp &lt;A href="http://msdn.microsoft.com/de-de/library/5kzh1b5w(VS.80).aspx"&gt;int&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Wo kann &lt;EM&gt;var&lt;/EM&gt; überall eingesetzt werden?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Das Schlüsselwort kann nur für lokale Variablen genutzt werden, so sind automatisch auch anonyme Typen nur in diesem Bereich nutzbar. D.h. es können auch keine anonymen Typen über Methodengrenzen hinaus übergeben werden.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Wo macht es Sinn var einzusetzen und wann ist ein var mehr zuviel?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Das ist eine spannende Frage und eigentlich der Kernpunkt dieses Streitgespräches. &lt;BR&gt;Hier einfach mal ein paar Beispiele:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; SetProperties() &lt;br /&gt;{ &lt;br /&gt;  var collectionMapping &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.CollectionMapping; &lt;br /&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(collectionMapping.Count() &amp;gt; 0) &lt;br /&gt;  { &lt;br /&gt;    collectionMapping.Clear(); &lt;br /&gt;  } &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; SetProperties() &lt;br /&gt;{ &lt;br /&gt;  ICollectionMapping collectionMapping &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;this&lt;/span&gt;.CollectionMapping; &lt;br /&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(collectionMapping.Count() &amp;gt; 0) &lt;br /&gt;  { &lt;br /&gt;    collectionMapping.Clear(); &lt;br /&gt;  } &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; RegisterType() &lt;br /&gt;{ &lt;br /&gt;    var objectToXElement &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; BuildObjectToXElementFunc&amp;lt;TEntity&amp;gt;(); &lt;br /&gt;    var xElementToObject &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; BuildXElementToObjectFunc&amp;lt;TEntity&amp;gt;(); &lt;br /&gt;&lt;br /&gt;    RegisterType(objectToXElement, xElementToObject); &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;static&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; RegisterType() &lt;br /&gt;{ &lt;br /&gt;    Func&amp;lt;TEntity, XElement&amp;gt; objectToXElement &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; BuildObjectToXElementFunc&amp;lt;TEntity&amp;gt;(); &lt;br /&gt;    Func&amp;lt;XElement, TEntity&amp;gt; xElementToObject &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; BuildXElementToObjectFunc&amp;lt;TEntity&amp;gt;(); &lt;br /&gt;&lt;br /&gt;    RegisterType(objectToXElement, xElementToObject); &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;oder sowas: &lt;BR&gt;&lt;BR&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;var wtf &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; GetPattern();&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;vs&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Pattern pattern &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; GetPattern();&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;In der ersten Methode wird var benutzt und in der folgenden dann nicht mehr. &lt;BR&gt;Ich habe die Beispiele extra so gewählt, denn wenn in diesen Methoden var benutzt wird, sieht man auf den ersten Blick (ohne die Maus zu benutzen, oder einen verrenkten Shortcut) nicht, um was für einen Typen es sich hier handelt.&lt;/P&gt;
&lt;P&gt;Und das ist natürlich ein sehr wichtiger Aspekt. &lt;BR&gt;Denn was nützt mir das weniger schreiben und weniger Code, wenn ich beim lesen – was übrigens vom Zeitaufwand deutlich mehr ist als das Schreiben – nicht mehr auf den ersten Blick erkennen kann, was für Typen das sind.&lt;/P&gt;
&lt;P&gt;Man sollte das Schlüsselwort im Regelfall wirklich &lt;U&gt;nur einsetzen um die anonymen Typen benutzen zu können&lt;/U&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Ausnahme wenn es sich um eine lange Typdefinition handelt _und_ initialisiert wird&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Ich für meinen Teil halte es so, das ich es eben dann benutze und zusätzlich auch noch in Fällen bei denen die Initialisierung (nicht Zuweisung) rechts daneben steht.&lt;/P&gt;
&lt;P&gt;Und das auch nur wenn es sich um eine lange und komplexere Typbezeichnung handelt, das sind dann meistens solche mit generischem Typparameter, Beispiel:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Foo() &lt;br /&gt;{ &lt;br /&gt;    Dictionary&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;, Person&amp;gt; persons &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;, Person&amp;gt; {…} &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Foo() &lt;br /&gt;{ &lt;br /&gt;    var persons &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt;, Person&amp;gt; {…} &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Durch den sprechenden Namen und dadurch das die Initialisierung der Variable und so auch die implizite Zuweisung des Types auf der rechten ist, kann das auch gut gelesen werden und ist praktikabel finde ich.&lt;/P&gt;
&lt;P&gt;Diese Anwendung hilft auch Redundanzen zu vermeiden. Wenn man bspw. die Initialisierung änderet ist der Typ auch automatisch angepasst. &lt;BR&gt;Das ist ein netter Nebeneffekt, kann aber auch böse enden, wenn man sich dessen nicht bewusst ist, das Interface gleich ist, aber sich die Methoden / Eigenschaften die später aufgerufen werden, anders verhalten.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Ausnahme wenn es um LINQ Abfragen handelt&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Bei LINQ Abfragen &lt;STRONG&gt;benötigt es &lt;U&gt;kein&lt;/U&gt; var&lt;/STRONG&gt;, wenn keine anonymen Typen genutzt werden. &lt;BR&gt;Allerdings halte ich es auch bei LINQ-Abfragen so, dass ich meistens var benutze. &lt;BR&gt;Denn mit guten Namen und im kleinen Kontext gehalten ist klar und verständlich was rüber kommt. Grösster Vorteil hierbei ist auch die automatische Anpassung des Types.&lt;/P&gt;
&lt;P&gt;Dies kommt in diesem Fall sehr zum Vorschein, denn durch Projektion kann sich der Rückgabetyp schnell ändern, obwohl die Eigenschaften bspw. gleich bleiben.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Foo() &lt;br /&gt;{ &lt;br /&gt;    IEnumerable&amp;lt;Person&amp;gt; persons &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; from person &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; list.Persons where person.Age &amp;gt; 20 select person; &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Foo() &lt;br /&gt;{ &lt;br /&gt;    var persons &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; from person &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;in&lt;/span&gt; list.Persons where person.Age &amp;gt; 20 select person; &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Das wars auch schon mit den Ausnahmen. Alles andere ist in meinen Augen nicht mehr lesbar und auch nicht gerechtfertigt. &lt;BR&gt;Ich finde es schon ein wenig beängstigend, wenn ich im Web (Auch von Microsoft) Beispiele sehen, die Zahlen und Zeichenfolgen in 20, 30 Zeilen nur mit var arbeiten. &lt;BR&gt;Wenn die Variablennamen dann noch schlecht gewählt, gute Nacht.&lt;/P&gt;
&lt;P&gt;Was denkt ihr über die Sache und vorallem über meine genannten Ausnahmen?&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=212562" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="Tipps" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Tipps/default.aspx" /><category term=".NET 3.5" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/.NET+3.5/default.aspx" /><category term="Streitgespr&amp;#228;ch" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Streitgespr_26002300_228_3B00_ch/default.aspx" /><category term="LINQ" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/LINQ/default.aspx" /><category term="var" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/var/default.aspx" /></entry><entry><title>ASP.NET Sicherheit - Directory Traversal verhindern</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/08/15/asp-net-sicherheit-directory-traversal-verhindern.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/08/15/asp-net-sicherheit-directory-traversal-verhindern.aspx</id><published>2009-08-15T11:12:00Z</published><updated>2009-08-15T11:12:00Z</updated><content type="html">&lt;P&gt;Im &lt;A href="http://de.wikipedia.org/wiki/Directory_Traversal"&gt;Wikipedia Artikel&lt;/A&gt; ist schon gut und ausführlich beschrieben, was unter “Directory Traversal” zu verstehen ist, Zitat:&lt;/P&gt;
&lt;DIV class=Quotes&gt;Unter Directory Traversal versteht man eine Sicherheitslücke in Web-Programmen wie z. B. einem Webserver oder einer Webanwendung, bei der durch Manipulation von Pfadangaben auf beliebige Dateien und Verzeichnisse zugegriffen werden kann, die dafür eigentlich nicht vorgesehen waren. Diese kann so ausgenutzt werden, dass sensible Daten wie Passwörter preisgegeben werden.&lt;/DIV&gt;
&lt;P&gt;Was kann der Entwickler dagegen tun? &lt;BR&gt;Im besten Fall eine &lt;A href="http://msdn.microsoft.com/de-de/library/system.guid.aspx"&gt;Guid&lt;/A&gt; / Id benutzen, um Dateien anzusprechen, jedoch ist das eine Mehrarbeit und manchmal nicht gewollt.&lt;/P&gt;
&lt;P&gt;Hier noch kurz ein Fall, der auf Directory Traversal anfällig ist:&lt;/P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; xmlBasePath &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Server.MapPath(“~/App_Data/XmlData/”); &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; xmlFilePath &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Path.Combine(xmlBasePath, Request.QueryString[“filename”]); &lt;br /&gt;XmlDocument document &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; XmlDocument(); &lt;br /&gt;document.Load(xmlFilePath);&lt;/span&gt;&lt;/code&gt; 
&lt;P&gt;In diesem Fall sieht der Pfad am Schluss so aus: “C:\Pfad\Zum\Web\App_Data\..\bild.xml” &lt;BR&gt;Wie man sieht, ist das Zurückgehen per “../” noch nicht aufgelöst, dies macht entweder Server.MapPath() oder bspw. auch andere Parteien wie bspw. XmlDocument innerhalb der Load()-Methode.&lt;/P&gt;
&lt;P&gt;Server.MapPath() wurde im oberen Beispiel aber nur für die Auflösung des Basispfades genutzt, darum hat sie keinen Einfluss. &lt;BR&gt;Beim nächsten Beispiel ist wieder die selbe Situation, nur das hier Server.MapPath() den Pfad auflöst:&lt;/P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; xmlBasePath &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; “~/App_Data/XmlData/”; &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; filePath &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Server.MapPath(Path.Combine(xmlBasePath, Request.QueryString[“filename”])); &lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// weiterer Code…..&lt;/span&gt;&lt;/span&gt;&lt;/code&gt; 
&lt;P&gt;Der Wert vom Benutzer – also Request.QueryString[“filename”] – kann also eine “../” Zeichenfolge vor dem Dateinamen selber enthalten und evt. sogar andere Pfadangaben.&lt;/P&gt;
&lt;P&gt;Wenn der Benutzer richtig böse ist, kann er so versuchen an einen anderen Ort innerhalb des Webs oder – bei schlechten Sicherheitseinstellungen – sogar des Webservers zu gelangen.&lt;/P&gt;
&lt;P&gt;Die simpelste Abwehrmethode ist das Ersetzen von allen möglichen Vorkommnissen von “../”. &lt;BR&gt;Jedoch ist das mühsam und immer noch nicht 100% sicher, denn über eine Eingabe von&amp;nbsp;“/secureimages/image.jpg” kommt der Benutzer immer noch an eine Datei in einem geschützten Unterordner(App_Data ist grundsätzlich geschützt) ran.&lt;/P&gt;
&lt;P&gt;Das&amp;nbsp;denkbar schlimmste Horroszenario wäre die Übernahme einer Datenbank oder oder sogar des Servers, was so durchaus machbar wäre.&lt;/P&gt;
&lt;P&gt;Die einfachste und zugleich auf effektivste Abwehrmassnahme ist die Benutzung von &lt;A href="http://msdn.microsoft.com/de-de/library/system.io.path.getfilename.aspx"&gt;Path.GetFileName&lt;/A&gt;(&amp;lt;Wert vom Benutzer&amp;gt;);&lt;/P&gt;
&lt;P&gt;Im oben stehenden Wikipedia Artikel ist noch beschrieben, dass auch &lt;A href="http://de.wikipedia.org/wiki/URL-Kodierung"&gt;Url kodierte Zeichen&lt;/A&gt; genutzt werden können und dann die erste hier vorgestellte Lösung unwirksam wird. &lt;BR&gt;Dies muss bei ASP.NET nicht beachtet werden, da bei Request.QueryString[] immer “../” ankommt, die Methode dekodiert also die Werte in der Url schon.&lt;/P&gt;
&lt;P&gt;Ein angriffssicheres Beispiel sieht dann so aus:&lt;/P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; xmlBasePath &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Server.MapPath(“~/App_Data/XmlData/”); &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; xmlFileName &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Path.GetFileName(Request.QueryString[“filename”]); &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; xmlFilePath &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Path.Combine(xmlBasePath, xmlFileName); &lt;br /&gt;&lt;br /&gt;XmlDocument document &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; XmlDocument(); &lt;br /&gt;document.Load(xmlFilePath);&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=212190" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="ASP.NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx" /><category term="Artikel" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Artikel/default.aspx" /><category term="Request" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Request/default.aspx" /><category term="Directory Traversal" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Directory+Traversal/default.aspx" /><category term="Sicherheit" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Sicherheit/default.aspx" /></entry><entry><title>C# oder VB: Welche Sprache soll ich lernen?</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/08/01/c-oder-vb-welche-sprache-soll-ich-lernen.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/08/01/c-oder-vb-welche-sprache-soll-ich-lernen.aspx</id><published>2009-08-01T07:37:00Z</published><updated>2009-08-01T07:37:00Z</updated><content type="html">&lt;P&gt;Am 13. Oktober 2008 haben &lt;A href="http://www.des-eisbaeren-blog.de/"&gt;Golo Roden&lt;/A&gt; und ich unter dem Titel &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/10/13/noch-fragen-roden-ja-bucher.aspx"&gt;Noch Fragen, Roden? Ja, Bucher!&lt;/A&gt; angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen. Bisher sind in dieser Reihe folgende Kommentare erschienen: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;1. Juli 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/07/01/prim-rschl-ssel-guid-vs-identity.aspx"&gt;Primärschlüssel: GUID vs Identity&lt;/A&gt; 
&lt;LI&gt;1. Juni 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/06/01/heisst-die-zukunft-ria.aspx"&gt;Heißt die Zukunft RIA?&lt;/A&gt; 
&lt;LI&gt;1. Mai 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/05/01/woran-erkennt-man-einen-guten-entwickler.aspx"&gt;Woran erkennt man einen guten Entwickler?&lt;/A&gt; 
&lt;LI&gt;1. April 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/04/01/interfaces-vs-abstrakte-klassen.aspx"&gt;Interfaces vs abstrakte Klassen&lt;/A&gt; 
&lt;LI&gt;1. März 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/03/01/sinn-und-zweck-von-aop.aspx"&gt;Sinn und Zweck von AOP&lt;/A&gt; 
&lt;LI&gt;1. Februar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/02/01/die-forderung-nach-softwarequalit-t.aspx"&gt;Die Forderung nach Softwarequalität&lt;/A&gt; 
&lt;LI&gt;1. Januar 2009: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/01/01/soa-vs-woa.aspx"&gt;SOA vs WOA&lt;/A&gt; 
&lt;LI&gt;1. Dezember 2008: &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/12/01/dynamic-language-runtime-net-quo-vadis.aspx"&gt;Dynamic Language Runtime: .NET, quo vadis?&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Heute, am 1. Juli 2009, ist es nun wieder so weit, und unser Thema für diesen Monat lautet: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;C# oder VB: Welche Sprache soll ich lernen?&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;So wohl Golo wie auch ich haben uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen. Außerdem nimmt diesen Monat auch &lt;A href="http://www.hauser-wenz.de/"&gt;Christian Wenz&lt;/A&gt; an unserem Streitgespräch teil.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.des-eisbaeren-blog.de/post/2009/08/01/C-oder-VB-Welche-Sprache-soll-ich-lernen.aspx"&gt;Golos&lt;/A&gt; und &lt;A href="http://www.hauser-wenz.de/s9y/index.php?/archives/282-C-oder-VB-Welche-Sprache-soll-ich-lernen.html"&gt;Christians&lt;/A&gt; Kommentare finden sich zeitgleich in den entsprechenden Blogs, folgend nun mein Kommentar zu diesem Thema:&lt;/P&gt;
&lt;P&gt;Also gleich vorneweg, es geht hier nicht um eine Glaubensfrage und auch nicht um “C# vs VB.NET” das bei einer Google Suche knapp 7 Millionen Treffer &lt;A href="http://www.google.ch/search?hl=de&amp;amp;q=c%23+vs+vb.net&amp;amp;meta="&gt;ergibt&lt;/A&gt; und von denen die meisten in einem Glaubenskrieg ausarten.&lt;/P&gt;
&lt;P&gt;Ich werde zwar auch C# vs VB.NET ansprechen, jedoch neutral und nüchtern verglichen sowie auf den Titel dieses Streitgespräches bezogen.&lt;/P&gt;
&lt;P&gt;Zuerst meine Erfahrungen zu diesem Thema:&lt;/P&gt;
&lt;P&gt;Ich habe den Einstieg in die Programmierung mit VBScript (Classic ASP) und ein wenig Javascript gefunden. &lt;BR&gt;Es gab zu dieser Zeit auch die Möglichkeit JScript zu benutzen, um Classic ASP zu entwickeln, jedoch gab es viel weniger Beispielcode dazu im Netz und mir kam die Syntax für einen Anfänger nicht wirklich natürlich und intuitiv vor.&lt;/P&gt;
&lt;P&gt;Später machte ich dann neben Visual Basic 6 auch Versuche in PHP (Ja, Jevoha &lt;A href="http://www.aspnetzone.de/blogs/stefanfalz/"&gt;Stefan&lt;/A&gt; ;-)). &lt;BR&gt;Desto mehr ich Erfahrungen sammelte und auch mit Sprachen die C ähnliche Syntax aufwiesen, herumexperimentierte, desto mehr wandte sich meine Einstellung das diese Art von Syntax doch nicht so unnatürlich und unintuitiv wirkt.&lt;/P&gt;
&lt;P&gt;Im gleichen Zug fand ich dann auch, das die kompaktere Art der Syntax den Code eleganter machte und auch auf das wesentliche reduzierte.&lt;/P&gt;
&lt;P&gt;Das waren meine Gründe das ich bei meinem Start in die .NET Welt gleich mit C# losgelegt habe. &lt;BR&gt;Am Anfang war das natürlich eine ziemliche Umstellung und vorallem der Switch, wieder mal VBScript zu schreiben und zurück auf C# komisch.&lt;/P&gt;
&lt;P&gt;Bei meinem ersten Arbeitsgeber musste ich dann erzwungenermassen VB.NET entwickeln, weil die bestehende Software darauf basierte. &lt;BR&gt;Am Anfang habe ich mir natürlich ein wenig schwer getan, jedoch sitzte die andere Syntax innerhalb von zwei Wochen schon sehr gut. Das ist natürlich auch meinen Erfahrungen mit VBScript zu verdanken, sodass die Elemente und Konventionen doch nicht so fremd waren.&lt;/P&gt;
&lt;P&gt;Mit der Zeit fand ich richtig Gefallen an VB.NET. Wichtig und zugleich interessant war für mich zu dieser Zeit (Da ich immer noch C# präferierte), dass ich privat immer mit C# gearbeitet habe.&lt;/P&gt;
&lt;P&gt;Schlussendlich bin ich froh das ich "erzwungenermassen” mit VB.NET arbeiten musste und dabei auch C# nicht aus den Augen verloren habe. Der Horizont wird erweitert und wenn irgendwo mal was in VB.NET steht, versteht man auch was damit gemeint ist.&lt;/P&gt;
&lt;P&gt;Auch wegen meiner Erfahrungen denke ich, das es für komplette Anfänger leichter ist mit VB.NET einzusteigen, da die Sprache am Anfang natürlicher und intuitiver erscheint. Nicht ohne Grund, denn der Ursprung von VB.NET wurde genau für diesen Zweck entwickelt, eine einsteigerfreundliche Sprache zu sein.&lt;/P&gt;
&lt;P&gt;Nun, das war jetzt meine Situation und meine Einschätzung. Was kann den generell dazu gesagt werden?&lt;/P&gt;
&lt;P&gt;Wenn jemand schon Erfahrungen in einer anderen Sprache hat, die auf dem BASIC-Dialekt basiert, wird er es beim Umstieg mit VB.NET sicher bequemer haben.&lt;/P&gt;
&lt;P&gt;Schlussendlich ist es (fast) eine reine Geschmacksfrage, was jemand bevorzugt oder auch was ihm besser liegt.&lt;/P&gt;
&lt;P&gt;Da VB.NET und C# bis auf das Aussehen der Syntax im Hintergrund genau dasselbe Paket haben und im Moment bis auf ein paar Featureungleichheiten das gleiche leisten, kommt es in den allermeisten Fällen auch nicht darauf an welches Feature jetzt von der zu lernenden Sprache unterstützt wird.&lt;/P&gt;
&lt;P&gt;Folgend finden sich noch zwei Verleichsauflistungen von C# und VB.NET:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Visual_Basic_.NET"&gt;Comparison of C Sharp and Visual Basic .NET&lt;/A&gt; (Wikipedia) 
&lt;LI&gt;&lt;A href="http://www.codeproject.com/KB/dotnet/vbnet_c__difference.aspx"&gt;Complete Comparison for VB.NET and C#&lt;/A&gt; (Codeproject) &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Ich bin jetzt mal ganz böse und möchte behaupten das es gar nicht so schlecht ist, wenn zuerst – also in der Anfangszeit - mit einer untypisierten und nicht objektorientierten Sprache geübt wird. &lt;BR&gt;So kann man sich ohne grosse Hindernisse und Dinge die Zeit und Wissen benötigen um sie zu verstehen, mit den grundlegenden Dingen der Programmierung beschäftigen, strukturiert. Wenn dies möglichst modular gelernt wird, ist dann auch der Umstieg auf eine objektorientierte Sprache – die ja auch die Konzepte der Strukturen beinhaltet – einfacher und nicht so überladen.&lt;/P&gt;
&lt;P&gt;Bei vielen Integrationen wie die von Tools in Visual Studio (bspw. ReSharper) oder der Unterstützung von VB.NET auf &lt;A href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/A&gt; hinkt VB.NET hinterher. Dasselbe gilt auch für die Unterstützung der Sprache in anderen IDEs. &lt;BR&gt;Auch ist es so, das die meisten grossen und bekannten Open Source Projekte meistens in C# geschrieben sind. &lt;BR&gt;Und wissentlich ist die Einsicht in fremden Quellcode für das Lernen unabginglich und &lt;EM&gt;sehr&lt;/EM&gt; zu empfehlen.&lt;/P&gt;
&lt;P&gt;An verschiedenen Quellen habe ich gelesen, das C# Entwickler auf dem Arbeitsmarkt besser bezahlt werden und das mehr Stellen vorhanden sind, wo C# gefordert wird. &lt;BR&gt;Wieviel da wirklich dran ist, kann ich nur gefühlsmässig einschätzen und würde da zustimmen. Es gibt sicherlich irgendwo noch Statistiken dazu.&lt;/P&gt;
&lt;P&gt;C# hat auch den Vorteil, das der Umstieg zu anderen Sprachen die C ähnliche Syntax benutzt, wie bspw. Java, leichter fällt.&lt;/P&gt;
&lt;P&gt;Wie sieht es nun mit der Weiterentwicklung und dem Support für VB.NET und C# in der Zukunft aus?&lt;/P&gt;
&lt;P&gt;Microsoft will in nächster Zukunft eine Featuregleichheit von C# und VB.NET erreichen, sodass sich die Sprachen featuremässig ebenwürdig sind. Das finde ich eine gute Entwicklung und stärkt die Position von VB.NET als Nummer zwei der Sprachen für das .NET Framework.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Fazit:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Um direkt auf die Titelfrage zu antworten, würde ich sagen: Lernt beide Sprachen, nein, lernt so viele Sprachen wie möglich. Allerdings fokusiert euch auf eine, damit ihr dort sehr gut werdet / bleibt.&lt;/P&gt;
&lt;P&gt;Wenn es darum geht mit welcher Frage man anfangen soll, bleibt es schlussendlich dem Geschmack überlassen. &lt;BR&gt;Im jetzigen Stand haben beide Kontrahenten jeweils Features die der andere nicht hat, jedoch sind diese in den meisten Fällen zu vernachlässigen. Das heisst, alle wichtigen Merkmale und Funktionen ist bei beiden vorhanden. &lt;BR&gt;Und das reicht für den Einstieg mehr als aus.&lt;/P&gt;
&lt;P&gt;Wichtiger finde ich, das einem späteren Umstieg eigentlicht nichts im Wege steht und das sich die Geschmäcker mit der Zeit auch ändern können.&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=211881" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="C#" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/C_2300_/default.aspx" /><category term="VB.NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/VB.NET/default.aspx" /><category term="Streitgespr&amp;#228;ch" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Streitgespr_26002300_228_3B00_ch/default.aspx" /><category term="Lernen" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Lernen/default.aspx" /></entry><entry><title>.NET Stammtisch Konstanz-Kreuzlingen – Die nächsten fünf Treffen im Überblick</title><link rel="alternate" type="text/html" href="http://www.aspnetzone.de/blogs/peterbucher/archive/2009/07/28/net-stammtisch-konstanz-kreuzlingen-die-n-chsten-f-nf-treffen-im-berblick.aspx" /><id>http://www.aspnetzone.de/blogs/peterbucher/archive/2009/07/28/net-stammtisch-konstanz-kreuzlingen-die-n-chsten-f-nf-treffen-im-berblick.aspx</id><published>2009-07-28T17:42:00Z</published><updated>2009-07-28T17:42:00Z</updated><content type="html">&lt;P&gt;&lt;A href="http://dotnetkk.de/"&gt;&lt;IMG style="DISPLAY:inline;MARGIN-LEFT:0px;MARGIN-RIGHT:0px;" align=right src="http://www.aspnetzone.de/photos/juergengutsch/images/206171/original.aspx"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;A href="http://dotnetkk.de/Appointments/Archive"&gt;6 Treffen&lt;/A&gt; liegen schon hinter uns und&amp;nbsp;wegen dem&amp;nbsp;&lt;A href="http://ulm.netopenspace.de/2009/"&gt;.NET Open Space Süd 2009&lt;/A&gt; (&lt;A href="http://ulm.netopenspace.de/2009/Schwarzes%20Brett.ashx"&gt;Berichte und Fotos dazu&lt;/A&gt;) Treffen wurde das letzte Treffen in einem kleinen Rahmen gehalten.&lt;/P&gt;
&lt;P&gt;Die Entwicklung der grenzübergreifenden Usergroup geht schneller voran als &lt;A href="http://www.aspnetzone.de/blogs/juergengutsch/"&gt;Jürgen&lt;/A&gt; und ich gedacht hatten. Das ist natürlich erfreulich!&lt;/P&gt;
&lt;P&gt;Dank &lt;A href="http://europe.ineta.org/Countries/Germany/Home/tabid/178/Default.aspx"&gt;INETA (International .NET Association) Deutschland&lt;/A&gt; haben wir die Möglichkeit bekommen, bekannte Sprecher zu sehr interessanten Themen zu gewinnen.&lt;/P&gt;
&lt;P&gt;Die &lt;A href="http://dotnetkk.de/Appointments"&gt;nächsten fünf Treffen&lt;/A&gt; stehen fest, unten findet ihr eine Zusammenfassung aller kommenden Treffen.&lt;/P&gt;
&lt;P&gt;Wir halten es so, dass es bei jedem Treffen einen Vortrag gibt, anschliessend jedoch genügend Zeit bleibt um bei einem Bierchen darüber zu diskutieren, damit die Teilnehmer auch aktiv werden und die Sprechern Feedback empfangen und zusätzliche Fragen beantworten können.&lt;/P&gt;
&lt;P&gt;Wenn ihr Vorschläge für Themen oder eine andere Art für ein Treffen habt, könnt ihr uns jederzeit mit den &lt;A href="http://dotnetkk.de/Content/Show/Imprint"&gt;Kontaktangaben&lt;/A&gt; auf der Homepage erreichen.&lt;/P&gt;
&lt;P&gt;Die nächsten Treffen finden alle bei der Fachhochschule in Konstanz statt und unter jedem Link für ein Treffen, findet ihr den &lt;A href="http://dotnetkk.de/Content/Show/Anfahrt"&gt;Anfahrtsplan&lt;/A&gt; und ggf. eine andere Ortsangabe, wenn wir uns zur Abwechslung mal zu einem Bierchen treffen wollen.&lt;/P&gt;
&lt;P&gt;Das &lt;A href="http://dotnetkk.de/Appointments/Details/sechstes-treffen-des-net-stammtisch-konstanz-kreuzlingen"&gt;sechste .NET-Stammtisch Treffen&lt;/A&gt; findet mit &lt;A href="http://www.artiso.com/problog/"&gt;Thomas Schissler&lt;/A&gt; und folgendem Thema statt:&lt;/P&gt;
&lt;DIV class=Quotes&gt;&lt;STRONG&gt;Überblick über VSTS 2010.&lt;/STRONG&gt; &lt;BR&gt;Mit Visual Studio Team System 2010 bring Microsoft eine neue Genereation siner Entwicklungsplattform auf den Markt.&lt;BR&gt;Neben einer großen Anzahl von Verbesserungen bring VSTS 2010 und das Backendsystem TFS 2010 auch völlig neue Funktionen und Möglichkeiten mit. Der Vortrag beleuchtet die verschiedenen Bereiche und stellt jeweils die wichtigsten Neuerungen vor. &lt;BR&gt;&lt;BR&gt;Diese werden mit verschiedenen Praxisbeispielen plastisch erläutert. &lt;BR&gt;Vorgetragen wird das Thema von Thomas Schissler.&lt;BR&gt;Thomas ist Leiter die Software-Entwicklung bei der Artiso AG in Ulm, Gründungsmitglied und Team-Leader der .NET Developer-Group Ulm und MVP für den Bereich Team System. Desweiteren ist Thomas viel als Sprecher auf großen Konferenzen und in User Group unterwegs. Das Weblog von Thomas, mit vielen Beiträgen zum Thema VSTS, ist unter folgender URL zu finden: &lt;A href="http://www.artiso.com/problog/"&gt;http://www.artiso.com/problog/&lt;/A&gt; &lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Das &lt;A href="http://dotnetkk.de/Appointments/Details/siebtes-treffen-des-net-stammtisch-konstanz-kreuzlingen"&gt;siebte .NET-Stammtisch Treffen&lt;/A&gt; findet mit &lt;A href="http://www.goloroden.de/"&gt;Golo Roden&lt;/A&gt; zu folgendem Thema statt: &lt;/P&gt;
&lt;DIV class=Quotes&gt;&lt;STRONG&gt;Dependency Hell? Nein, danke!. &lt;BR&gt;&lt;/STRONG&gt;Code verfügt nicht erst seit Objekten und Komponenten, die aufeinander aufbauen, über innere Abhängigkeiten.&lt;BR&gt;Doch welche Abhängigkeiten sind gut, welche schlecht? Golo Roden zeigt in dieser Session, welche gängigen Arten von Abhängigkeiten es in der Dependency Hell gibt und erläutert grundlegene theoretische Begriffe und Konzepte wie beispielsweise Kohäsion und Kopplung, implizite und explizite Abhängigkeit und Separation of Concerns.&lt;BR&gt;Die Vorstellung passender Gegenmaßnahmen und ihrer Anwendung – vom einfachen Refactoring auf Quellcode- bis hin zum Einsatz eines Microkernels auf Architekturebene – runden die Session mit kleinen Praxisbeispielen schließlich ab. &lt;BR&gt;&lt;BR&gt;Golo Roden lebt seit dem Jahr 2005 in Freiburg im Breisgau und ist Autor, Sprecher und Trainer für .NET und verwandte Technologien. Er beschäftigt sich mit Software Engineering, Applikationsarchitektur, Infrastruktur und Webtechnologien im Allgemeinen. Golo ist verheiratet und Vater einer Tochter, hat einen Collie wie auch eine Schwäche für Eisbären und beschäftigt sich in seiner Freizeit mit elektronischer Musik, digitaler Fotografie und Kochen.&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Das &lt;A href="http://dotnetkk.de/Appointments/Details/achtes-treffen-des-net-stammtisch-konstanz-kreuzlingen"&gt;achte .NET-Stammtisch Treffen&lt;/A&gt; findet mit &lt;A href="http://www.aspnetzone.de/blogs/juergengutsch/"&gt;Jürgen Gutsch&lt;/A&gt; und folgendem Thema statt: &lt;/P&gt;
&lt;DIV class=Quotes&gt;&lt;STRONG&gt;ASP.NET Best Practices&lt;/STRONG&gt;. &lt;BR&gt;&lt;A href="http://www.aspnetzone.de/blogs/juergengutsch/"&gt;Jürgen Gutsch&lt;/A&gt; beschreibt in einem Vortrag, wie man optimal mit ASP.NET Anwendungen schreibt, ohne im Durcheinander von PostBacks und ViewStates nicht mehr weiter zu kommen.&lt;BR&gt;Sowie PostBacks sparsam und gezielt einsetzt werden und wie man den ViewState klein hält und somit auch die Performance optimiert hält.&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Das &lt;A href="http://dotnetkk.de/Appointments/Details/neuntes-treffen-des-net-stammtisch-konstanz-kreuzlingen"&gt;neunte .NET-Stammtisch Treffen&lt;/A&gt; findet mit &lt;A href="http://webenliven-space.de/dotnetblog/"&gt;Gregor Biswanger&lt;/A&gt; und folgendem Thema statt: &lt;/P&gt;
&lt;DIV class=Quotes&gt;&lt;STRONG&gt;TDD / BDD &lt;BR&gt;&lt;/STRONG&gt;Ein neues Software Projekt beginnt. Das Design der Architektur steht auch schon. Nun können die hoch motivierten Entwickler starten, ihre Fachbereiche mit Code zu füllen. Doch kommt es schon nach kurzer Zeit zu großen Problemen! Die Anwendung macht an unterschiedlichen Stellen alles andere als das, was gefordert wurde. Keiner kann am Ende sagen woran das liegt, jeder versucht seine Position zu verteidigen. Ist das Projekt nun zum Scheitern verurteilt? Wird nun der Fertigstellungstermin noch weiter nach hinten geschoben, der sowieso schon an der Schmerzgrenze lag?! Nein, durch Test Driven Development kann dieses Problem verringert werden. Damit ist nicht die Fehleranfälligkeit gemeint, sondern das rechtzeitige Erkennen, an welcher Stelle es gerade nicht funktioniert wie es soll. 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Einführung in Test Driven Development&lt;/STRONG&gt; &lt;BR&gt;Was ist überhaupt TDD? Wie kann ich TDD für neue oder bestehende Projekte richtig nutzen? Welche Arten von Testmöglichkeiten für heutige Softwareprojekte geboten wird, soll auch verdeutlicht werden. Dabei wird einmal die Theorie und anschließend die Praxis genauestens durchleuchtet. Dementsprechend werden dabei folgende Punkte besprochen: Unit-Tests, Integrations-Tests, Akzeptanz-Tests und Mocking.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Theorie &amp;amp; Praxis: Code-Coverage&lt;/STRONG&gt; &lt;BR&gt;Sehr oft wird beim Schreiben von Codes genau an denn Tests geschrieben, die niemals zu Problemen eintreffen werden. Somit passieren Fehler, die bis heute im Unbekannten weiter leben. Damit diese Horrorvisionen nicht Wirklichkeit wird, spielt die Testabdeckung eine wichtige Rolle!&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Einführung in Behavior Driven Development&lt;/STRONG&gt; &lt;BR&gt;Durch eine Erweiterung von TDD durch Behavior-Driven Development (kurz BDD) werden Tests strukturierter nach den Anforderungen aufgebaut. Hier wird unverkennbar der Kern von TDD für qualitative Softwareprojekte genutzt, und durch die Erweiterung von BDD die funktionalen Anforderungen in den Mittelpunkt gestellt.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Über den Sprecher &lt;BR&gt;&lt;/STRONG&gt;Gregor Biswanger ist Consultant bei der Firma TRIA IT-solutions in München. Seine Schwerpunkte liegen im Bereich der .NET-Architektur und agilen Prozessen. &lt;BR&gt;Biswanger ist auch freier Autor, Speaker und Microsoft CLIPler der INdotNET (Ingolstädter .NET Developers Group).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Verlosung: Fuzzing-Tests für .NET mit CrashTest.Net &lt;BR&gt;&lt;/STRONG&gt;CrashTest.Net ist ein Testwerkzeug, das explizit auf .NET-Projekte zugeschnitten ist und eine bisher für das .NET-Umfeld ungenutzte Testmethode verwendet. Bei der Testmethode handelt es sich um Fuzzing. Es hilft Entwicklern ihre Software zu optimieren und zeigt ihnen unbedachte Fälle, die später beim Endnutzer fatale Folgen haben können. Ohne notwendige Einstellungen führt es vollautomatisch eine sehr große Anzahl von Tests an ihrer .NET-Assembly durch. Es versucht alle Methoden mit sehr vielen Parametern auszuführen. Und all das, ohne vorher komplizierte Einstellungen zu vorzunehmen oder im Quellcode irgendwelchen Test-Code zu implementieren. Fuzzing birgt ein sehr großes Potential. Dieses Potential wird der .NET-Welt mit CrashTest.Net einen entscheidenden Schritt näher gebracht.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;CrashTest.Net unterstützt uns freundlicherweise mit 1 Lizenz zur Verlosung&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Das &lt;A href="http://dotnetkk.de/Appointments/Details/zehntes-treffen-des-net-stammtisch-konstanz-kreuzlingen"&gt;zehnte .NET-Stammtisch&lt;/A&gt; Treffen findet mit &lt;A href="http://www.aspnetzone.de/blogs/juergengutsch/"&gt;Jürgen Gutsch&lt;/A&gt; und folgendem Thema statt: &lt;/P&gt;
&lt;DIV class=Quotes&gt;&lt;STRONG&gt;Barrierefreie Anwendungen mit ASP.NET. &lt;BR&gt;&lt;/STRONG&gt;Jürgen Gutsch beschreibt in einem Vortrag, ob es möglich ist Barrierefreie Webentwicklung mit ASP.NET zu betreiben und zeigt anhand von Beispielen was nötig ist um Barrierearme Anwendungen zu Entwickeln &lt;BR&gt;&lt;BR&gt;Anschließend wird wie immer beim gemütlichen Bierchen weiter diskutiert, bzw. im Advent ist natürlich Glühwein auf dem Konstanzer Waihnachtsmarkt angesagt :-) &lt;/DIV&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=211770" width="1" height="1"&gt;</content><author><name>Peter Bucher</name><uri>http://www.aspnetzone.de/members/Peter+Bucher.aspx</uri></author><category term="Community" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Community/default.aspx" /><category term=".NET" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/.NET/default.aspx" /><category term="Konstanz" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Konstanz/default.aspx" /><category term="Kreuzlingen" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Kreuzlingen/default.aspx" /><category term="dotnetkk.de" scheme="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/dotnetkk.de/default.aspx" /></entry></feed>