<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Powershell</title>
        <link>http://blogs.escde.net/sascha/category/16.aspx</link>
        <description>Powershell</description>
        <language>en-US</language>
        <copyright>Sascha</copyright>
        <managingEditor>frietsch@escde.net</managingEditor>
        <generator>Subtext Version 1.9.3.0</generator>
        <item>
            <title>Windows PowerShell in Action</title>
            <link>http://blogs.escde.net/sascha/archive/2007/06/13/80.aspx</link>
            <description>&lt;p&gt;Von Manning Publications ist im Februar das Buch &lt;em&gt;Windows PowerShell in Action&lt;/em&gt; von Bruce Payette erschienen, das ich durchaus lesenswert fand.&lt;/p&gt; &lt;p&gt;Unter [1] gibt es jetzt Probekapitel zum kostenfreien Download. Kapitel 1 gibt einen Einstieg in Windows Powershell. Anhang C erklärt die anfänglich etwas gewöhnungsbedürftige Grammatik von Powershell.&lt;/p&gt; &lt;p&gt;[1] Windows PowerShell in Action, &lt;a title="http://www.manning.com/payette/" href="http://www.manning.com/payette/"&gt;http://www.manning.com/payette/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.escde.net/sascha/aggbug/80.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Sascha</dc:creator>
            <guid>http://blogs.escde.net/sascha/archive/2007/06/13/80.aspx</guid>
            <pubDate>Wed, 13 Jun 2007 09:27:54 GMT</pubDate>
            <comments>http://blogs.escde.net/sascha/archive/2007/06/13/80.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.escde.net/sascha/comments/commentRss/80.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.escde.net/sascha/services/trackbacks/80.aspx</trackback:ping>
        </item>
        <item>
            <title>Powershell 03 - Das erste Cmdlet erstellen</title>
            <link>http://blogs.escde.net/sascha/archive/2007/03/02/67.aspx</link>
            <description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;Die wichtigsten Namespaces im Überblick:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;System.Management.Automation&lt;/strong&gt; - This is the root namespace for Windows PowerShell. It contains the classes, enumerations, and interfaces required to implement custom cmdlets. In particular, the Cmdlet class is the base class from which all custom cmdlet classes must be derived from.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;System.Management.Automation.Provider&lt;/strong&gt; - This namespace contains the classes, enumerations, and interfaces required to implement a Windows PowerShell provider. In particular, the CmdletProvider class is the base class from which all Windows PowerShell provider classes must be derived.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Microsoft.PowerShell.Commands&lt;/strong&gt;: This namespace contains the cmdlets implemented by Windows PowerShell. In a similar fashion, it is recommended that you create a [YourName].Commands namespace for those cmdlets that you implement.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;System.Management.Automation.Host&lt;/strong&gt;: This namespace contains the classes, enumerations, and interfaces that the cmdlet uses to interact with the Host application user.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;System.Management.Automation.Internal&lt;/strong&gt;: This namespace contains the base classes used by other namespace classes. For example, the CmdletMetadataAttribute class is the base class for the CmdletAttribute class.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;System.Management.Automation.Runspaces&lt;/strong&gt;: This namespace contains the classes, enumerations, and interfaces used to create an Windows PowerShell Runspace. In this context, the Windows PowerShell Runspace is the context in which one or more Windows PowerShell pipelines invoke cmdlets. That is, cmdlets do their work within the context of an Windows PowerShell Runspace.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Die Cmdlets in diesem und den nächsten Beispielen bieten Zugriff auf die ID3Tag-Informationen von MP3-Dateien. Ist nicht wirklich aufregend und ich bin mir sicher, dass ich nicht der erste bin, der auf diese Idee kommt. Um die verschiedenen Facetten der Cmdlet-Entwicklung zu betrachten, sollte das aber ausreichen. &lt;/p&gt; &lt;p&gt;Zum Auslesen der ID3Tags verwende ich die &lt;a title="ID3Sharp Library" href="http://id3sharp.sourceforge.net/" target="_blank"&gt;ID3Sharp Library&lt;/a&gt; von Chris Woods, die man auf sourceforge.net finden kann. &lt;/p&gt; &lt;p&gt;In einem Klassenbibliothek-Projekt müssen zunächst zwei Verweise hinzugefügt werden:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;System.Management.Automation - siehe oben, wird immer gebraucht, wenn ein Cmdlet erstellt werden soll. Im &lt;em&gt;Verweis hinzufügen&lt;/em&gt;-Dialog auf den Tab &lt;em&gt;Durchsuchen&lt;/em&gt; wechseln und die Dll &lt;strong&gt;C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll &lt;/strong&gt;auswählen  &lt;/li&gt;&lt;li&gt;System.Configuration.Install.dll - wird für das Snap-in benötigt, das unser Cmdlet später in der Powershell registriert. Näheres später. Zu finden im &lt;em&gt;Verweis hinzufügen&lt;/em&gt;-Dialog auf dem Tab &lt;em&gt;.Net&lt;/em&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Ein Cmdlet muss immer die Basisklasse System.Management.Automation.Cmdlet erweitern. In Powershell setzt sich der Name von Cmdlets aus einem Verb-Substantiv-Paar zusammen, so z.B. Get-Service, Move-Item, etc... Die Namensgebung ist durchgängig und dabei recht einfach zu durchschauen. Die gängigsten Verben finden sich, nach Kategorien gruppiert, in einigen Enumerationen im System.Management.Automation-Namensraum, z.B. VerbsCommon, VerbsSecurity. Diese sollte man nach Möglichkeit auch in eigenen Cmdlets verwenden, um Konsistenz in der Powershell-Benutzung für den Anwender zu wahren.   &lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:4418bbee-4fdd-4edb-a266-dc4ea803c67a" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;[Cmdlet(VerbsCommon.Get, &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Mp3FileInfo&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;)]
&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; GetMp3FileInfoCommand : Cmdlet
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;protected&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;void&lt;/span&gt;&lt;span style="color: #000000; "&gt; ProcessRecord()
    {
        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Ausgabeobjekte in die Pipeline geben&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;        WriteObject(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Das Mp3FileInfo Cmdlet steht zur Verfügung&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Um den Namen für das Cmdlet zu definieren, wird die öffentliche Klasse mit dem Cmdlet-Attribut versehen, dem Verb und Substantiv mitgegeben werden. Der Klassenname selbst ist unerheblich für die Verwendung in Powershell. Die einzige Methode, die überschrieben werden muss, is ProcessRecord(). In dieser Methode führt das Cmdlet seine Funktionen aus. Die Rückgabeobjekte werden dann mit Hilfe der WriteObject-Methode der Basisklasse in die Powershell-Pipeline geschrieben.&lt;/p&gt;
&lt;p&gt;Das war's auch schon. Ziemlich unspektakulär.&lt;/p&gt;
&lt;p&gt;Was zum ersten Test noch fehlt, ist ein Snap-in. Snap-ins registrieren benutzerdefinierte Cmdlets und Provider in der Powershell, damit diese von der Kommandozeile aus aufrufbar werden.&lt;/p&gt;
&lt;p&gt;Zwei Sorten von Snap-ins stehen zur Auswahl. Ich wähle hier die einfache Variante, die die Klasse PSSnapIn erweitert. Diese Art von Snap-in registriert alle verfügbaren Cmdlets und Provider innerhalb der eigenen Assembly. Die Luxusvariante erweitert CustomPSSnapIn. Mit einem CustomPSSnapIn ist es möglich, nur bestimmte Cmdlets und/oder Provider innerhalb der eigenen, oder einer anderen Assembly zu registrieren.&lt;/p&gt;
&lt;p&gt;Für das Snap-in wird eine neue Klasse zum Projekt hinzugefügt.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5ea7a881-a7a4-42d2-818c-95cda529f10d" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;[RunInstaller(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;true&lt;/span&gt;&lt;span style="color: #000000; "&gt;)]
&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; Mp3FileInfoSnapIn : PSSnapIn
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; Mp3FileInfoSnapIn()
        : &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;base&lt;/span&gt;&lt;span style="color: #000000; "&gt;()
    {
    }

    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000; "&gt;
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; Specify the name of the PowerShell snap-in.
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; Name
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt;
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Mp3FileInfoSnapIn&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
        }
    }

    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000; "&gt;
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; Specify the vendor for the PowerShell snap-in.
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; Vendor
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt;
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;ESCde&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
        }
    }

    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000; "&gt;
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; Specify the localization resource information for the vendor. 
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; Use the format: resourceBaseName,VendorName. 
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; VendorResource
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt;
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Mp3FileInfoSnapIn,ESCde&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
        }
    }

    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000; "&gt;
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; Specify a description of the PowerShell snap-in.
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; Description
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt;
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Registers all Mp3FileInfo Cmdlets.&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
        }
    }

    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000; "&gt;
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; Specify the localization resource information for the description. 
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; Use the format: resourceBaseName,Description. 
    &lt;/span&gt;&lt;span style="color: #808080; "&gt;///&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #808080; "&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; DescriptionResource
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt;
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Mp3FileInfoSnapIn,Registers all Mp3FileInfo Cmdlets.&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
        }
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sieht nach viel aus, ist es aber nicht. Das einzige, was der Entwickler hier zu tun hat, ist das Überschreiben von fünf String-Eigenschaften zur Beschreibung des Snap-ins. Der Rest wird von der Basisklasse geregelt. Wichtig ist, dass die Snap-in-Klasse von dem RunInstaller(true)-Attribut dekoriert wird. Das Attribut ist im System.ComponentModel Namespace definiert. Das RunInstaller-Attribut dient dem Installutil Tool bei der Installation der Assembly als Hinweis. Installutil.exe überprüft die angegebene Assembly mittels Reflexion und sucht alle Installer-Typen, bei denen für das RunInstaller-Attribut true festgelegt wurde. Anschließend führt das Tool für jede Instanz des Installer-Typs entweder die Install-Methode oder die Uninstall-Methode aus. PSSnapin ist indirekt von solch einem Installer abgeleitet, der in der referenzierten Assembly System.Configuration.Install.dll definiert ist. &lt;/p&gt;
&lt;p&gt;Jetzt kann das Projekt kompiliert werden.&lt;/p&gt;&lt;img src="http://blogs.escde.net/sascha/aggbug/67.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Sascha</dc:creator>
            <guid>http://blogs.escde.net/sascha/archive/2007/03/02/67.aspx</guid>
            <pubDate>Fri, 02 Mar 2007 14:21:04 GMT</pubDate>
            <comments>http://blogs.escde.net/sascha/archive/2007/03/02/67.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.escde.net/sascha/comments/commentRss/67.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.escde.net/sascha/services/trackbacks/67.aspx</trackback:ping>
        </item>
        <item>
            <title>Custom Generic Collections oder: Filtern und Sortieren Teil 2</title>
            <link>http://blogs.escde.net/sascha/archive/2007/03/01/66.aspx</link>
            <description>&lt;p&gt;Im letzten Post hatte ich eine List&amp;lt;T&amp;gt; mit Hilfe von IComparer&amp;lt;T&amp;gt; und Predicate&amp;lt;T&amp;gt; sortiert bzw. gefiltert. Das hatte so weit auch funktioniert. Das einzige, was mir an dieser Lösung noch nicht gefällt: Wenn ich mich dafür entscheiden sollte, meine MP3-Dateien jetzt nach einem Artist statt nach einem Titel zu filtern, muss ich zuerst eine entsprechende Funktion dazu erstellen, dann das Prädikat erzeugen, was auf diese Funktion zeigt, und dieses dann beim Aufruf der FindAll-Methode verwenden. Das gleiche beim Sortieren. Der vorhandene Mp3Comparer sortiert nur nach Artist. Neue Sortierung, neuer Comparer. Das muss doch einfacher gehen...&lt;/p&gt; &lt;p&gt;Die Lösung bietet Reflection. Zumindest in meinem Fall. Reflection ist Gift für die Performance, so dass man bei großen Listen evtl. ein Problem mit den Laufzeiten der Sort-Methode bekommt, wenn bei der Erstellung der Sortierordnung jedes Listenelement mehrfach mittels Reflection untersucht werden muss. &lt;/p&gt; &lt;p&gt;An den Comparer wird der Name der Eigenschaft übergeben, in der Compare-Methode wird die Eigenschaft und deren Werte per Reflection aus den zu vergleichenden Elementen ermittelt und das Ergebnis des Vergleichs zurückgeliefert.  &lt;/p&gt; &lt;p&gt;Der bisherige MP3Comparer ist speziell auf den Vergleich von Instanzen des Typs ID3Tag ausgelegt, da er auf die Eigenschaften Titel und Artist angewiesen ist. Daher war er auch vom Typ IComparer&amp;lt;ID3Tag&amp;gt;. Der neue Comparer, den ich ReflectionComparer getauft habe, ist hingegen für alle Typen geeignet, daher vom Typ IComparer&amp;lt;T&amp;gt;. Der Comparer funktioniert aber nur, wenn der Typ der Eigenschaften, deren Werte verglichen werden sollen, selbst das IComparable Interface implementiert. Für die Standarddatentypen wie String, Int32, etc. ist dies erfüllt.&lt;/p&gt; &lt;p&gt;Der komplette Code für den neuen Comparer sieht nun folgendermaßen aus: &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:6cab7ae5-25da-44b3-8508-c0d40700f0fe" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; ReflectionComparer&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; : IComparer&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;
{
    SortType sortType;
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortPropertyName;

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; ReflectionComparer(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortPropertyName)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.sortPropertyName &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortPropertyName;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.sortType &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; SortType.Ascending;
    }

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; ReflectionComparer(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortPropertyName,
        SortType sortType)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.sortPropertyName &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortPropertyName;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.sortType &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortType;
    }

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;#region&lt;/span&gt;&lt;span style="color: #000000; "&gt; IComparer&amp;lt;T&amp;gt; Members&lt;/span&gt;&lt;span style="color: #000000; "&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt; Compare(T x, T y)
    {
        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Mittels Reflection die Werte 
        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt;der Eigenschaften aus x und y bestimmen&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; valueX &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.GetType().GetProperty(
            sortPropertyName).GetValue(x, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; valueY &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; y.GetType().GetProperty(
            sortPropertyName).GetValue(y, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
        
        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Der Typ der Eigenschaft muss IComparable implementieren&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;        IComparable comparable &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; (IComparable)valueX;
        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Wert x mit Wert y vergleichen&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; (&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt;)sortType &lt;/span&gt;&lt;span style="color: #000000; "&gt;*&lt;/span&gt;&lt;span style="color: #000000; "&gt; comparable.CompareTo(valueY);
    }
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;#endregion&lt;/span&gt;&lt;span style="color: #000000; "&gt;
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Auf sämtliche Fehlerbehandlung wurde in diesen Beispielen verzichtet. Gerade bei Reflection ist das aber wichtig, weil der Kompiler keinen Fehler meldet, wenn wir nach einem Feld sortieren wollen, das es gar nicht gibt. In der Form kann ich den IComparer wie gehabt an die Sort-Methode von List&amp;lt;T&amp;gt; anhängen. Ich möchte den Aufruf jedoch etwas intuitiver kapseln, so dass ich die Liste mit&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7af871f4-3768-40ac-b8dd-7cd9f0d4cc5e" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;id3Tags.Sort(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Artist&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, SortType.Ascending);
id3Tags.Sort(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Album&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, SortType.Descending);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;entsprechend sortieren kann. Das heißt, ich muss eine eigene Generic Collection erzeugen. Es wäre jetzt naheliegend, diese CustomGenericCollection von System.Collections.Generic.List abzuleiten. Dies sollte man nach den Empfehlungen von Microsoft jedoch nicht tun, da List&amp;lt;T&amp;gt; eine große Anzahl von öffentlichen Methoden und Eigenschaften besitzt, die in den meisten Szenarien nicht relevant sind. Das heißt nicht, dass man nicht von List&amp;lt;T&amp;gt; erben könnte. Wenn man z.B. nur eine weitere Methode hinzufügen möchte, dann kann es schon Gründe geben, es auf diesem Weg machen. Es ist aber nicht möglich, sich in die Eventkette der Liste einzuklinken. Muss z.B. beim Löschen eines Elements aus der Liste ein Logeintrag erstellt werden, ist List&amp;lt;T&amp;gt; als Basisklasse nicht zu verwenden. Überhaupt bietet List&amp;lt;T&amp;gt; keine überschreibbaren Member, was auch ein Zeichen dafür ist, dass diese Klasse nicht zum vererben gemacht wurde. Auch sollten keine List&amp;lt;T&amp;gt; Objekte als Eigenschaften von Klassen nach außen gegeben werden. &lt;/p&gt;
&lt;p&gt;FXCop meldet einen DoNotExposeGenericLists Fehler mit dem Hinweis: "System.Collections.Generic.List&amp;lt;T&amp;gt; is a generic collection designed for&lt;br /&gt;performance not inheritance and, therefore, does not contain any virtual members. The following generic collections are designed for inheritance and&lt;br /&gt;should be exposed instead of System.Collections.Generic.List&amp;lt;T&amp;gt;. &lt;br /&gt;* System.Collections.ObjectModel.Collection&amp;lt;T&amp;gt;&lt;br /&gt;* System.Collections.ObjectModel.ReadOnlyCollection&amp;lt;T&amp;gt;&lt;br /&gt;* System.Collections.ObjectModel.KeyedCollection&amp;lt;TKey, TItem&amp;gt;"&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/kcwalina/default.aspx" target="_blank"&gt;Krzysztof Cwalina&lt;/a&gt; (Program Manager .Net Framework team at MS)  hat in einem Blogpost &lt;a href="http://blogs.msdn.com/kcwalina/archive/2005/09/23/Collections.aspx" target="_blank"&gt;"System.Collections vs. System.Collection.Generic and System.Collections.ObjectModel"&lt;/a&gt; die verschiedenen Collection-Klassen und -Interfaces in den verschiedenen Namespaces in einer Übersicht zusammengestellt. Auch sehr hilfreich war ein Auszug des Wrox Buches "&lt;a href="http://www.wrox.com/WileyCDA/Section/id-290685.html" target="_blank"&gt;Professional C# 2005&lt;/a&gt;"&lt;/p&gt;
&lt;p&gt;Anders die Klasse Collection&amp;lt;T&amp;gt;, die in der MSDN als "base class for a generic collection" beschrieben wird. Diese gehört aber nicht zum Namensraum System.Collections.Generic, sondern findet sich in System.Collections.ObjectModel. Grund dafür ist eine gleichnamige, nichtgenerische Collection Klasse aus dem Microsoft.VisualBasic Namensraum, der bei Visual Basic Klassen, ebenso wie System.Collections.Generic, standardmäßig importiert wird und es dadurch zu Namenskonflikten kommen kann. &lt;br /&gt;Nach aussen sind bei der Collection&amp;lt;T&amp;gt; Klasse nur die nötigsten Eigenschaften und Methoden verfügbar und intern kann die innere Liste über die Items-Eigenschaft abgegriffen werden. Zudem bietet Collection&amp;lt;T&amp;gt; überschreibbare Methoden zur Benachrichtigung bei Änderungen an der Liste, d.h. bei Hinzufügen, Aktualisieren und Löschen von Elementen. Das hört sich doch gut an, eine CustomGenericCollection ist dann schnell erstellt. &lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:e877f9f4-b4d1-4358-a6ae-f56a20486426" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; CustomGenericCollection&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; : System.Collections.ObjectModel.Collection&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;protected&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;void&lt;/span&gt;&lt;span style="color: #000000; "&gt; InsertItem(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt; index, T item)
        {
            &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Aktion, wenn Item hinzugefügt wird&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;base&lt;/span&gt;&lt;span style="color: #000000; "&gt;.InsertItem(index, item);
        }
        
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; T[] ToArray()
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; ((List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;)&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;base&lt;/span&gt;&lt;span style="color: #000000; "&gt;.Items).ToArray();
        }

        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;void&lt;/span&gt;&lt;span style="color: #000000; "&gt; Sort(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortPropertyName)
        {
            Sort(sortPropertyName, SortType.Ascending);
        }
        
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;void&lt;/span&gt;&lt;span style="color: #000000; "&gt; Sort(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortPropertyName, SortType sortType)
        {
            ReflectionComparer&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; comparison &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; 
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; ReflectionComparer&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;(sortPropertyName, sortType);
            ((List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;)&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;base&lt;/span&gt;&lt;span style="color: #000000; "&gt;.Items).Sort(comparison);
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Neben den zwei Sort-Methoden, die die innere Liste mit dem ReflectionComparer von oben aufrufen, wird zusätzlich noch die ToArray-Methode der inneren Liste nach außen geführt, die in Collection&amp;lt;T&amp;gt; der Schlankheit zuliebe eingespart wurde. In der Insert-Methode könnte man das Hinzufügen eines neuen Elements zur Liste protokollieren oder auch unterbinden.&lt;/p&gt;
&lt;p&gt;Die Filterung sollte auch noch etwas einfacher vonstatten gehen. Das Vorgehen ist wieder ähnlich. Die bisherige Filtermethode, die mittels Prädikat an die FindAll-Methode der List&amp;lt;T&amp;gt; übergeben wurde, wollte ein Objekt vom Typ ID3Tag übergeben bekommen. Da der neue GenericFilter ebenfalls mit Reflection arbeitet, ist der Typ der generischen Filtermethode egal. Wenn eine Instanz von GenericFilter erzeugt wird, muss ihr im Konstruktor der Name der zu filternden Eigenschaft, der Vergleichswert sowie optional ein Operator mitgegeben werden. Der Code der Klasse GenericFilter sieht dann so aus:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:14e4dc13-1442-461a-ae28-a5ca5ffdbac9" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;internal&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; GenericFilter
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterPropertyName &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;""&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterValue &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;""&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
    FilterOperator filterOperator;

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; GenericFilter(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterPropertyName, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterValue)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.filterPropertyName &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterPropertyName;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.filterValue &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterValue;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.filterOperator &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; FilterOperator.Contains;
    }

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; GenericFilter(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterPropertyName, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterValue, 
        FilterOperator filterOperator)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.filterPropertyName &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterPropertyName;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.filterValue &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterValue;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.filterOperator &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterOperator;
    }

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;bool&lt;/span&gt;&lt;span style="color: #000000; "&gt; Filter&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;(T x)
    {
        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Mittels Reflection die Werte 
        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; der Eigenschaften aus x und y bestimmen&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; valueX &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.GetType().GetProperty(
            filterPropertyName).GetValue(x, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;);

        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;switch&lt;/span&gt;&lt;span style="color: #000000; "&gt; (filterOperator)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;case&lt;/span&gt;&lt;span style="color: #000000; "&gt; FilterOperator.Contains:
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (Convert.ToString(valueX).Contains(filterValue))
                    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;true&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;break&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;case&lt;/span&gt;&lt;span style="color: #000000; "&gt; FilterOperator.Equals:
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (Convert.ToString(valueX).Equals(filterValue))
                    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;true&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;break&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;case&lt;/span&gt;&lt;span style="color: #000000; "&gt; FilterOperator.GreaterThan:
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (Convert.ToInt32(valueX).CompareTo(Convert.ToInt32(filterValue)) &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;)
                    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;true&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;break&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;case&lt;/span&gt;&lt;span style="color: #000000; "&gt; FilterOperator.LessThan:
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (Convert.ToInt32(valueX).CompareTo(Convert.ToInt32(filterValue)) &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;)
                    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;true&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;break&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;default&lt;/span&gt;&lt;span style="color: #000000; "&gt;:
                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;false&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
        }
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;false&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Der Filter kann für Texteigenschaften die Operatoren Contains und Equals anwenden und für ganzzahlige Eigenschaften einen GreaterThan oder LessThan Vergleich anstellen. Auch hier wieder eine ziemlich laxe Fehlerbehandlung ;-) &lt;/p&gt;
&lt;p&gt;Wie dem auch sei, jetzt muss nur noch die FindAll-Methode meiner CustomGenericCollection das Prädikat mit dem Verweis auf die neue Filter-Funktion erstellen und das dann an die FindAll-Methode der inneren Liste weiterreichen. Als Ergebnis wird ein Array vom Typ T nach außen gegeben.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:25ffd844-8498-43a2-95d6-480a98760186" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; T[] FindAll(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterPropertyName, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterValue, FilterOperator filterOperator)
{
    GenericFilter genericFilter &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; GenericFilter(filterPropertyName, filterValue, filterOperator);

    &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Prädikat vorbereiten&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;    Predicate&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterGeneric &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Predicate&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;(genericFilter.Filter&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
    &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Filtern und als Array zurückgeben&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; ((List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;T&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;)&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;base&lt;/span&gt;&lt;span style="color: #000000; "&gt;.Items).FindAll(filterGeneric).ToArray();
}

&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; T[] FindAll(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterPropertyName, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterValue)
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; FindAll(filterPropertyName, filterValue, FilterOperator.Contains);
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Die Liste von ID3Tags muss noch auf den neuen Typ CustomGenericCollection umgestellt werden.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:1f993d8a-c13e-4f7a-870f-8e5b1ddc1027" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt;List&amp;lt;ID3Tag&amp;gt; id3Tags = new List&amp;lt;ID3Tag&amp;gt;();&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;CustomGenericCollection&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; id3Tags &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; CustomGenericCollection&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nun lässt sie sich anständig filtern:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:560f1b4e-922d-42ab-8fed-a81a7ae0ecc1" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;ID3Tag[] filteredItemsArray;
filteredItemsArray &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; 
    id3Tags.FindAll(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Year&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;1990&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, FilterOperator.GreaterThan);
filteredItemsArray &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt;
    id3Tags.FindAll(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Title&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Love&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, FilterOperator.Contains);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Ich hätte die neuen Filter- und Sortiermethoden nicht unbedingt generisch halten müssen. Nimmt man den geringen Mehraufwand in Kauf, wird man mit hoher Wiederverwendbarkeit belohnt, wie der folgende und letzte Codefetzen zeigt. Was er tut, erahnen Sie sicherlich. &lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:aad27be3-dc7c-4ad3-8193-e346ba068b12" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; Person
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; nachname;
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; vorname;

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; Person(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; nachname, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; vorname)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.nachname &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; nachname;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.vorname &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; vorname;
    }

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; Nachname
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt; { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; nachname; }
    }
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; Vorname
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt; { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; vorname; }
    }

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; ToString()
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; String.Format(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;{0}, {1}&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, nachname, vorname);
    }
}

...

CustomGenericCollection&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;Person&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; persColl &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; 
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; CustomGenericCollection&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;Person&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;();
persColl.Add(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Person(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Frietsch&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Sascha&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;));
persColl.Add(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Person(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Schimmel&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Jochen&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;));
persColl.Add(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Person(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Janczik&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Sebastian&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;));

persColl.Sort(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Nachname&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, SortType.Descending);
Person[] persArray &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; persColl.ToArray();

persArray &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; persColl.FindAll(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Vorname&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Sascha&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;, FilterOperator.Equals);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://blogs.escde.net/sascha/aggbug/66.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Sascha</dc:creator>
            <guid>http://blogs.escde.net/sascha/archive/2007/03/01/66.aspx</guid>
            <pubDate>Thu, 01 Mar 2007 17:58:23 GMT</pubDate>
            <comments>http://blogs.escde.net/sascha/archive/2007/03/01/66.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.escde.net/sascha/comments/commentRss/66.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.escde.net/sascha/services/trackbacks/66.aspx</trackback:ping>
        </item>
        <item>
            <title>Filtern von generischen Listen mit Hilfe von Pr&amp;auml;dikaten</title>
            <link>http://blogs.escde.net/sascha/archive/2007/03/01/65.aspx</link>
            <description>&lt;p&gt;Nachdem ich meine Liste von ID3Tags jetzt sortieren kann, fehlt noch das Filtern einer generischen Liste. &lt;/p&gt; &lt;p&gt;Die Typen System.Collections.Generic.List und System.Array stellen eine Reihe von Methoden zur Verfügung, die einen einzigen Parameter vom Typ Predicate&amp;lt;T&amp;gt; erwarten. &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Exists&lt;/li&gt; &lt;li&gt;Find&lt;/li&gt; &lt;li&gt;FindAll&lt;/li&gt; &lt;li&gt;FindIndex&lt;/li&gt; &lt;li&gt;FindLast&lt;/li&gt; &lt;li&gt;FindLastIndex&lt;/li&gt; &lt;li&gt;ForEach&lt;/li&gt; &lt;li&gt;RemoveAll&lt;/li&gt; &lt;li&gt;TrueForAll &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Für meinen Filter will ich die FindAll Methode verwenden, die als Ergebnis eine List&amp;lt;T&amp;gt; liefert, welche nur die Elemente der Ursprungsliste enthält, die das übergebene Prädikat erfüllen. &lt;/p&gt; &lt;p&gt;Prädikate sind eines der neuen generischen Features, die seit Version 2.0 des .Net Frameworks zur Verfügung stehen. Der Delegat System.Predicate wird wie folgt definiert:&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:84a8982e-e9c9-401f-980a-bf438fa1f1a9" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;Public Delegate Function Predicate(Of T)(obj As T) As Boolean&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Eine Funktion, die als Prädikat fungieren soll, muss also einen einzigen Parameter akzeptieren, der vom gleichen Typ sein muss, wie die Elemente der Liste, die mit Hilfe dieses Prädikats bearbeitet werden soll. Der Rückgabewert ist ein Booleanwert,  der angibt, ob das untersuchte Element in die Ergebnismenge übernommen werden soll.&lt;/p&gt;
&lt;p&gt;Um alle Instanzen von ID3Tags zu bekommen, deren Titel das Wort "Happy" enthält, könnte man einen Code in dieser Form verwenden: &lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7e95e251-e0cb-4d58-9335-fd1922d1bbba" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; compareValue &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Happy&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; titleFilteredList &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;(); 
&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;foreach&lt;/span&gt;&lt;span style="color: #000000; "&gt; (ID3Tag id3Tag &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;in&lt;/span&gt;&lt;span style="color: #000000; "&gt; id3Tags)
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (id3Tag.Title.Contains(compareValue))
    {
        titleFilteredList.Add(id3Tag);
    }
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alle Elemente der Ausgangsliste werden durchlaufen; wenn der Titel den gesuchten Wert enthält, wird das Element der Ergebnismenge angefügt. Achtung: in diesem Beispiel wird nur eine Referenz auf das Element in die Ergebnisliste angefügt, keine Kopie!&lt;/p&gt;
&lt;p&gt;Die FindAll-Methode funktioniert vom Prinizip her genauso wie die Schleife im obigen Code. Das übergebene Prädikat entspricht der Überprüfung innerhalb der Schleife. Es bestimmt, was beim einzelnen Element geprüft werden soll. Zunächst muss also eine Funktion definiert werden, die ein Element vom Typ ID3Tag entgegennimmt und nach der Überprüfung des Elements einen booleschen Wert zurückgibt. Der Vergleichswert wird schon im Konstruktor der SearchFilter-Klasse übergeben.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d6354f62-eb5a-4052-b469-fe29eb1ebe5d" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;internal&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; SearchFilter
    {
        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Vergleichswert&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; compareValue &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;""&lt;/span&gt;&lt;span style="color: #000000; "&gt;;

        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; SearchFilter(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; compareValue)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.compareValue &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; compareValue;
        }

        &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Suche nach Teil von Titel&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;bool&lt;/span&gt;&lt;span style="color: #000000; "&gt; TitleContains(ID3Tag id3Tag)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; id3Tag.Title.Contains(compareValue);
        }
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Jetzt kann das Prädikat erzeugt und der FindAll()-Methode übergeben werden. Das Prädikat ist - als Delegat - lediglich die Adresse einer aufrufbaren Methode. &lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:83b6ce0b-5049-47be-91dc-a822510e45ab" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt;Vergleichswert für Suche nach Titel im Konstruktor übergeben&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;SearchFilter titleSearchFilter &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; SearchFilter(&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;Happy&lt;/span&gt;&lt;span style="color: #000000; "&gt;"&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
&lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Prädikat vorbereiten&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;Predicate&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; filterByTitle &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt;
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Predicate&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;(titleSearchFilter.TitleContains);
&lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Liste mit gefiltertem Ergebnis&lt;/span&gt;&lt;span style="color: #008000; "&gt;
&lt;/span&gt;&lt;span style="color: #000000; "&gt;List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; titleFilteredList &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; id3Tags.FindAll(filterByTitle);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Die anderen Methoden, die ich oben erwähnt hatte und die ebenfalls ein Pedicate&amp;lt;T&amp;gt; als Parameter erwarten, funktionieren ähnlich. So iteriert Exists ebenfalls durch alle Elemente und gibt true zurück, wenn das Prädikat das erste mal für ein Element true zurückgibt. FindLastIndex durchläuft die Liste von hinten nach vorne und gibt den Index des Elements aus, bei dem das Prädikat das erste mal true zurückgibt, usw. Interessant sind auch die ForEach()- und RemoveAll()-Methoden.&lt;/p&gt;
&lt;p&gt;Mit Prädikaten spart man sich den Code, um durch Elemente einer Liste zu iterieren. OK, vielleicht nicht so triftig, dieser Grund. Aber bezüglich Wiederverwendbarkeit und Austauschbarkeit zur Laufzeit haben Prädikate ihren Charme.&lt;/p&gt;&lt;img src="http://blogs.escde.net/sascha/aggbug/65.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Sascha</dc:creator>
            <guid>http://blogs.escde.net/sascha/archive/2007/03/01/65.aspx</guid>
            <pubDate>Thu, 01 Mar 2007 11:21:16 GMT</pubDate>
            <comments>http://blogs.escde.net/sascha/archive/2007/03/01/65.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.escde.net/sascha/comments/commentRss/65.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.escde.net/sascha/services/trackbacks/65.aspx</trackback:ping>
        </item>
        <item>
            <title>Sortieren von generischen Listen</title>
            <link>http://blogs.escde.net/sascha/archive/2007/02/28/64.aspx</link>
            <description>&lt;p&gt;Ich war auf der Suche nach einem einigermaßen sinnvollen Beispiel für die Programmierung von Powershell Cmdlets. Das erste Cmdlet soll Informationen aus ID3Tags von MP3-Dateien auslesen. Man muss das Rad nicht jedesmal neu erfinden, daher verwende ich die Bibliothek ID3Sharp von Chris Woodbury, die man auf sourceforge.net finden kann.&lt;/p&gt; &lt;p&gt;Die MP3-Dateien aus einem Verzeichnis werden nacheinander eingelesen. Für jede Datei werden die Informationen aus dem ID3-Tag in einer Instanz vom Typ ID3Tag zurückgegeben. Diese besitzt lediglich einige öffentliche Eigenschaften für die gängigen Informationen wie Artist, Title, Album, etc. Diese einzelnen Instanzen von ID3Tags werden in einer generischen Liste gesammelt. &lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:0ca1138c-9251-4a78-8db8-fc84931ae768" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; id3Tags &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Es wäre schön, auf diese Liste nun Filter und Sortierungen anzuwenden. Geht natürlich auch ;-)&lt;/p&gt;
&lt;p&gt;Fangen wir mit dem Sortieren an. Die generische Klasse List&amp;lt;T&amp;gt; bietet von Haus aus eine Sort() Methode in drei möglichen Überladungen.&lt;/p&gt;
&lt;p&gt;List&amp;lt;T&amp;gt;.Sort () ohne weitere Argumente verwendet den default comparer. Das bedeutet, dass der Typ T das IComparable- oder das generische IComparable-Interface implementieren muss. Da dies bei ID3Tag nicht der Fall ist, würde sich die Liste bei einem Sort()-Aufruf mit einer InvalidOperationException bedanken.&lt;/p&gt;
&lt;p&gt;Für die beiden anderen Überladungen wird eine Vergleichsmethode benötigt, die als Parameter zwei Variablen vom Typ T verarbeiten muss, in unserem Falle also zwei Objekte vom Typ ID3Tag. Der Rückgabewert der Methode ist -1, 0 oder 1, je nachdem, ob x kleiner, gleich, oder größer y ist. Ich überlasse hier die Berechnung des Rückgabewertes der String.CompareTo()-Methode der Artist- bzw. Title-Eigenschaft.&lt;/p&gt;
&lt;p&gt;Für die Sortierung List&amp;lt;T&amp;gt;.Sort (Generic Comparison) muss die Vergleichsmethode in einer statischen Methode mit den oben erwähnten Parameter definiert werden:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:0c8eecb3-5143-4467-b848-89111967aceb" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;static&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt; CompareID3TagsByArtist(ID3Tag x, ID3Tag y)
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (x.Artist &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; y.Artist)
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.Title.CompareTo(y.Title);
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;else&lt;/span&gt;&lt;span style="color: #000000; "&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.Artist.CompareTo(y.Artist);
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Diese Methode habe ich in einer Klasse SearchFilter erstellt. Der Aufruf zum Sortieren der Liste lautet daher:&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:f3ab1803-b240-4c5f-9049-f7d9df887f79" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;id3Tags.Sort(SearchFilter.CompareID3TagsByArtist);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Die letzte Möglichkeit, List&amp;lt;T&amp;gt;.Sort(Generic IComparer), verstaut die Vergleichsmethode in einer eigenen Klasse, die das generische IComparer&amp;lt;T&amp;gt;-Interface implementiert. Um das Interface zu implementieren, muss exakt eine Methode erstellt werden - die Vergleichsmethode. Die ganze Klasse sieht dann so aus:&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7e47cbad-c85e-4f60-8677-04f24524830b" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;internal&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; Mp3Comparer : IComparer&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;ID3Tag&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;#region&lt;/span&gt;&lt;span style="color: #000000; "&gt; IComparer&amp;lt;ID3Tag&amp;gt; Members&lt;/span&gt;&lt;span style="color: #000000; "&gt;

    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt; Compare(ID3Tag x, ID3Tag y)
    {
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (x.Artist &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; y.Artist)
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.Title.CompareTo(y.Title);
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;else&lt;/span&gt;&lt;span style="color: #000000; "&gt;
            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.Artist.CompareTo(y.Artist);
    }
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;#endregion&lt;/span&gt;&lt;span style="color: #000000; "&gt;
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Für den Sortieraufruf muss dann ein Objekt vom Type Mp3Comparer erzeugt werden, welches an die Sortmethode übergeben wird.&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:35e11002-37e0-436b-a1aa-76f297db2d96" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;Mp3Comparer mc &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Mp3Comparer();
id3Tags.Sort(mc);&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Als letztes Schmankerl fehlt noch ein aufsteigendes oder absteigendes Sortieren. Dafür lässt sich der Code für die Mp3Comparer Klasse zum Beispiel wie folgt ändern:&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9db55453-df48-4d20-a887-ab662d858a9d" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;#region&lt;/span&gt;&lt;span style="color: #000000; "&gt; IComparer&amp;lt;ID3Tag&amp;gt; Members&lt;/span&gt;&lt;span style="color: #000000; "&gt;

&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt; Compare(ID3Tag x, ID3Tag y)
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (x.Artist &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; y.Artist)
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; (&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt;)sortType &lt;/span&gt;&lt;span style="color: #000000; "&gt;*&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.Title.CompareTo(y.Title);
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;else&lt;/span&gt;&lt;span style="color: #000000; "&gt;
        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; (&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt;)sortType &lt;/span&gt;&lt;span style="color: #000000; "&gt;*&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.Artist.CompareTo(y.Artist);
}

&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;#endregion&lt;/span&gt;&lt;span style="color: #000000; "&gt;

&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; Mp3Comparer()
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.sortType &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; SortType.Ascending;
}

&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; Mp3Comparer(SortType sortType)
{
    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;this&lt;/span&gt;&lt;span style="color: #000000; "&gt;.sortType &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; sortType;
}

&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;private&lt;/span&gt;&lt;span style="color: #000000; "&gt; SortType sortType;
&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;enum&lt;/span&gt;&lt;span style="color: #000000; "&gt; SortType {Descending &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;-&lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt;, Ascending &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Es ist ein neuer Konstruktor hinzugekommen, der eine Sortierrichtung als Parameter akzeptiert. Ist ein Nicht-Standardkonstruktor definiert, muss auch der Standardkonstruktor explizit angegeben werden. Die bisherige Sortierrichtung war aufsteigend. Dies soll auch der Standardwert sein, wenn keine Richtung angegeben wurde. Soll absteigend sortiert werden, wird der Rückgabewert von Compare gerade mit -1 multipliziert.&lt;/p&gt;
&lt;p&gt;Um die Liste nun absteigend zu sortieren, wird folgender Aufruf verwendet:&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:63136683-35dc-439a-9061-46b2a9073d95" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000; "&gt;Mp3Comparer mc &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Mp3Comparer(Mp3Comparer.SortType.Descending);
id3Tags.Sort(mc);
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src="http://blogs.escde.net/sascha/aggbug/64.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Sascha</dc:creator>
            <guid>http://blogs.escde.net/sascha/archive/2007/02/28/64.aspx</guid>
            <pubDate>Wed, 28 Feb 2007 18:08:01 GMT</pubDate>
            <comments>http://blogs.escde.net/sascha/archive/2007/02/28/64.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.escde.net/sascha/comments/commentRss/64.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.escde.net/sascha/services/trackbacks/64.aspx</trackback:ping>
        </item>
        <item>
            <title>Powershell 02 - Powershell per Gruppenrichtlinie verteilen</title>
            <link>http://blogs.escde.net/sascha/archive/2007/02/28/63.aspx</link>
            <description>&lt;p&gt;&lt;em&gt;&lt;strong&gt;[Update 08.03.2007]&lt;/strong&gt;&lt;/em&gt; &lt;br /&gt;
&lt;strong&gt;Verteilung der finalen Powershell Version per Software Installation Package ist nicht mehr möglich!&lt;/strong&gt; &lt;br /&gt;
&lt;br /&gt;
Hintergrund: Microsoft sieht Powershell als Teil des Betriebssystems. Momentan noch optional, man kann aber davon ausgehen, dass in zukünftigen Windows-Versionen oder Service Packs Powershell fester Bestandteil des Betriebssystems werden wird. Daher werden Teile der finalen Version von Powershell in das System32-Verzeichnis kopiert. Dies bedeutet gleichzeitig das Aus für die Verwendung von msi-Dateien, denen dies nicht erlaubt ist. Bis zur RC1-Version (wenn nicht sogar RC2) installierte sich Powershell noch unterhalb des Programme-Ordners, was mit einer msi Installation bewerkstelligt werden konnte (siehe How-To unten). Da sieht man mal wieder, dass RC noch nicht final ist…&lt;/p&gt;
&lt;p&gt;Laut einem &lt;a target="_blank" href="http://www.tek-tips.com/userinfo.cfm?member=markdmac"&gt;Technical Account Manager von Microsoft&lt;/a&gt; ist sich Microsoft dem Problem bewusst und arbeitet an einer Lösung für die Verteilung von Powershell mittels AD oder SMS. Um Powershell zur Zeit per Gruppenrichtlinie zu verteilen, bleibt nur die Installation via Startup-/ Logonscript, die funktionieren sollte, da die Installationsdatei mit einem /quiet Parameter aufgerufen werden kann. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;[Ende Update]&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;Das Microsoft Powershell Setup kommt als msi-Paket ins Haus und bietet daher die Windows Installer-üblichen Features. Unter anderem lässt sich ein msi-Paket per Gruppenrichtlinie verteilen und installieren. Das folgende How-To soll einfach nur zeigen, wie schnell so etwas erledigt ist.  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schritt 1:&lt;/strong&gt; Ordnerfreigabe erstellen, in der das/ die zu verteilenden msi-Pakete liegen. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schritt 2:&lt;/strong&gt; In der Group Policy Management Konsole ein neues Gruppenrichtlinienobjekt (GPO) erstellen.&lt;/p&gt;
&lt;p&gt;&lt;a target="_new" atomicselection="true" href="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell02PowershellperGruppenrichtlin_E99E/Bild-0002%5B3%5D.gif"&gt;&lt;img height="375" alt="" width="447" src="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell02PowershellperGruppenrichtlin_E99E/Bild-0002_thumb%5B1%5D.gif" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schritt 3:&lt;/strong&gt; Das erstellte Gruppenrichtlinienobjekt editieren.&lt;/p&gt;
&lt;p&gt;Unter Computer Configuration, Software Settings, Software installation wird hierzu ein neues Package erstellt. Dabei wird die Powershell_Setup-i386.msi über die soeben erstellte Freigabe ausgewählt.&lt;/p&gt;
&lt;p&gt;&lt;a target="_new" atomicselection="true" href="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell02PowershellperGruppenrichtlin_E99E/Bild-0005%5B3%5D.gif"&gt;&lt;img height="357" alt="" width="500" src="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell02PowershellperGruppenrichtlin_E99E/Bild-0005_thumb%5B1%5D.gif" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schritt 4:&lt;/strong&gt; Eine OU im Active Directory mit dem Gruppenrichtlinienobjekt von Schritt 2 verlinken.&lt;/p&gt;
&lt;p&gt;Im Beispiel hier wird die OU "member servers" mit dem GPO "Install Powershell" verlinkt.&lt;/p&gt;
&lt;p&gt;&lt;a target="_new" atomicselection="true" href="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell02PowershellperGruppenrichtlin_E99E/Bild-0007%5B5%5D.gif"&gt;&lt;img height="375" alt="" width="447" src="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell02PowershellperGruppenrichtlin_E99E/Bild-0007_thumb%5B3%5D.gif" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Schritt 5:&lt;/strong&gt; Die Installation überprüfen&lt;/p&gt;
&lt;p&gt;Auf einem der Memberserver wird die Powershell danach in der Systemsteuerung unter Software angezeigt. Dass die Powershell wirklich per Gruppenrichtlinie installiert wurde, sieht man auch im Anwendungs-Eventlog: dort findet sich nach einer erfolgreichen Installation der folgende Eintrag:&lt;/p&gt;
&lt;p&gt;&lt;a target="_new" atomicselection="true" href="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell02PowershellperGruppenrichtlin_E99E/Bild-0010%5B3%5D.gif"&gt;&lt;img height="375" alt="" width="338" src="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell02PowershellperGruppenrichtlin_E99E/Bild-0010_thumb%5B1%5D.gif" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.escde.net/sascha/aggbug/63.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Sascha</dc:creator>
            <guid>http://blogs.escde.net/sascha/archive/2007/02/28/63.aspx</guid>
            <pubDate>Wed, 28 Feb 2007 15:52:45 GMT</pubDate>
            <comments>http://blogs.escde.net/sascha/archive/2007/02/28/63.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.escde.net/sascha/comments/commentRss/63.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.escde.net/sascha/services/trackbacks/63.aspx</trackback:ping>
        </item>
        <item>
            <title>Powershell 01 - Hilfe, bitte!</title>
            <link>http://blogs.escde.net/sascha/archive/2007/02/23/62.aspx</link>
            <description>&lt;p&gt;&lt;/p&gt; &lt;p&gt;Dies ist der erste Teil einer kleinen Erkundung von Windows Powershell und ihren Möglichkeiten für Entwickler. Wie kann ich mein eigenes Cmdlet erstellen und wie kann ich die Powershellfunktionalität in eigenen Anwendungen verwenden? Bevor das erste eigene Cmdlet erstellt wird, sollte man sich zuerst einmal einen Überblick verschaffen, was Powershell an Funktionalität schon mitbringt. &lt;/p&gt; &lt;p&gt;Powershell gibt sich sehr hilfsbereit. Eine Übersicht aller zur Verfügung stehender Commandlets gibt es mit dem Befehl &lt;em&gt;Get-Command&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell01Hilfebitte_D428/Bild-0001%5B6%5D.png" target="_new" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="250" src="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell01Hilfebitte_D428/Bild-0001_thumb%5B2%5D.png" width="500" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Die wichtigsten Informationen zu einem Commandlet ruft man über G&lt;em&gt;et-Command -name &amp;lt;Commandlet-Name&amp;gt;&lt;/em&gt; ab. &lt;/p&gt; &lt;p&gt; Eigentlich benutze ich diesen Befehl nur, um Informationen zur Befehlssyntax zu bekommen, aber ausgerechnet von der sieht man in der Standardausgabe fast nichts. Wenn man den Switch &lt;em&gt;-usage&lt;/em&gt; setzt, sieht das schon besser aus.&lt;/p&gt; &lt;p&gt; &lt;a href="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell01Hilfebitte_D428/Bild-0002%5B3%5D.png" target="_new" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="250" src="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell01Hilfebitte_D428/Bild-0002_thumb%5B1%5D.png" width="500" border="0" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Ausfürhliche Hilfe zu einem Commandlet mit Beschreibung der einzelnen Parameter und Beispielen zur Verwendung gibt es mit dem Befehl &lt;em&gt;Get-Help -name &amp;lt;Commandlet-Name&amp;gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell01Hilfebitte_D428/Bild-0003%5B3%5D.png" target="_new" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="250" src="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell01Hilfebitte_D428/Bild-0003_thumb%5B1%5D.png" width="500" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Oft gibt es gleich so viel Information, dass der Anfang des Hilfetextes schon wieder aus dem Bildschirmpuffer der Konsole gescrollt ist, und auch die Bedienung ist nicht wirklich komfortabel. Zum Glück hat &lt;a href="http://secretgeek.net/shinyPower.asp" target="_blank"&gt;Leon the SecretGeek&lt;/a&gt; eine schicke kleine Anwendung geschrieben: einen Powershell-Hilfebrowser, der mit einer Kombination dieser zwei gezeigten Commandlets funktioniert. Die Liste im linken Bereich wird durch &lt;em&gt;Get-Command&lt;/em&gt; gefüllt. Bei Auswahl eines Commandlets wird dann ein entsprechendes Get-Help ausgeführt und im rechten Bildschirmbereich dargestellt.&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell01Hilfebitte_D428/Bild-0004%5B4%5D.png" target="_new" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="249" src="http://blogs.escde.net/images/blogs_escde_net_86/sascha/WindowsLiveWriter/Powershell01Hilfebitte_D428/Bild-0004_thumb%5B2%5D.png" width="500" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Diese Anwendung ist auch ein schönes Beispiel für einen Custom Application Host - also das Verwenden der Powershell(-funktionalität) in einer eigenen Anwendung. Dazu komme ich in einem späteren Post.&lt;/p&gt;&lt;img src="http://blogs.escde.net/sascha/aggbug/62.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Sascha</dc:creator>
            <guid>http://blogs.escde.net/sascha/archive/2007/02/23/62.aspx</guid>
            <pubDate>Fri, 23 Feb 2007 14:11:42 GMT</pubDate>
            <comments>http://blogs.escde.net/sascha/archive/2007/02/23/62.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.escde.net/sascha/comments/commentRss/62.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.escde.net/sascha/services/trackbacks/62.aspx</trackback:ping>
        </item>
    </channel>
</rss>