Tipp-Upload: VB.NET 0139: Predicates für Listen verwenden
von Dario
Über den Tipp
Dieser Tippvorschlag ist noch unbewertet.
Der Vorschlag ist in den folgenden Kategorien zu finden:
- Sonstiges
Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
Delegate, Predicate, Prädikat, List, TrueForAll, ForEach, AddressOf
Der Vorschlag wurde erstellt am: 02.11.2007 18:43.
Die letzte Aktualisierung erfolgte am 02.11.2007 18:43.
Beschreibung
Möchte man bestimmte Operationen oder Abfragen mit allen oder bestimmten Elementen einer List oder etwas Vergleichbarem machen, macht man das meißt mit For Each.
Eine andere und teilweise bequemere Methode ist das Arbeiten mit Prädikaten bzw. Funktionszeigern (Delegates).
Die List hat schon vorgefertigte Methoden, die für die Operation nur die Adresse einer Funktion brauchen.
Aber auch für sonstige Zwecke sind solche Ansätze interessant.
Schwierigkeitsgrad |
Verwendete API-Aufrufe: |
Download: |
' Dieser Source stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' ' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird. ' In den Zip-Dateien ist er jedoch zu finden. ' ----------- Anfang Projektgruppe Predicates.sln ----------- ' ---------- Anfang Projektdatei Predicates.vbproj ---------- ' ----------------- Anfang Datei Module1.vb ----------------- Option Explicit On Option Strict On Imports System Imports System.Collections.Generic Namespace Predicates ''' <summary> ''' Basisklasse für Sortiersimulation ''' </summary> Class BaseSort Protected mStr As String Public Sub New(ByVal Str As String) mStr = Str End Sub Public Property Str() As String Get Return mStr End Get Friend Set(ByVal value As String) mStr = value End Set End Property ' Delegatendeklarationen für Konvertierung in String Public Shared ReadOnly CnvToString As New System.Converter(Of BaseSort, String)( _ AddressOf ConvertToString) Private Shared Function ConvertToString(ByVal Cls As BaseSort) As String Return Cls.Str End Function End Class ''' <summary> ''' Per IComparable sortieren ''' </summary> Class SortByIComparable Inherits BaseSort Implements System.IComparable(Of SortByIComparable) Public Sub New(ByVal Str As String) MyBase.New(Str) End Sub Public Function CompareTo(ByVal other As SortByIComparable) As Integer Implements _ System.IComparable(Of SortByIComparable).CompareTo Return String.Compare(mStr, other.Str) End Function End Class ''' <summary> ''' Mit Prädikat sortieren ''' </summary> Class SortByPredicate Inherits BaseSort Public Sub New(ByVal Str As String) MyBase.New(Str) End Sub ' Den Delegaten speichern Public Shared ReadOnly Comparison As New System.Comparison(Of SortByPredicate)( _ AddressOf mComparison) ' Prädikatfunktion Private Shared Function mComparison(ByVal a As SortByPredicate, ByVal b As _ SortByPredicate) As Integer Return String.Compare(a.Str, b.Str) End Function End Class ''' <summary> ''' Hauptmodul ''' </summary> ''' <remarks></remarks> Module Module1 ' Die zu sortierenden Strings Private ReadOnly Strings As String() = {"Hallo, Welt", "String1", "12", "String2", _ "String15", "121"} Sub Main() Dim ICmpList As New List(Of SortByIComparable) Dim PredList As New List(Of SortByPredicate) Dim BaseList As New List(Of BaseSort) ' Füllen For Each s As String In Strings ICmpList.Add(New SortByIComparable(s)) PredList.Add(New SortByPredicate(s)) BaseList.Add(New BaseSort(s)) Next Console.WriteLine("Simulation von Prädikaten und Delegaten für Listen") ' Simulation zum Sortieren Show(ICmpList, "Original") Show(PredList, "Original") ' Sortieren: Einmal hat die Klasse IComparable implementiert, die andere ' definiert einen Delegaten für das Sortieren ICmpList.Sort() PredList.Sort(SortByPredicate.Comparison) Show(ICmpList, "Sortiert (IComparable)") Show(PredList, "Sortiert (Prädikat)") ' Simulation für Converter ' Eine Stringliste Dim StrList As List(Of String) = BaseList.ConvertAll(Of String)(BaseSort.CnvToString) ' Simulation für Remove BaseList.RemoveAll(AddressOf Predicates.RemoveString) Show(BaseList, "Alle Werte, die mit ""String"" beginnen, entfernt") ' Simulation für Find Dim MyArray As BaseSort() = BaseList.ToArray ' Arrays können das auch ' Gibt es numerische Werte? If Array.Exists(MyArray, AddressOf Predicates.Numbers) Then Console.Write("Numerische Werte: ") For Each Number As BaseSort In Array.FindAll(MyArray, AddressOf Predicates.Numbers) Console.Write("{0}; ", Convert.ToInt32(Number.Str)) Next End If ' Simulation für TrueForAll ' Gibt es nur numerische Werte in der Liste? Console.WriteLine("{1}Gibt es nur numerische Werte in der Liste? : {0}", IIf( _ BaseList.TrueForAll(AddressOf Predicates.Numbers) = True, "Ja", "Nein"), _ Environment.NewLine) ' Simulation für ForEach BaseList.ForEach(AddressOf Predicates.ToUCase) Console.WriteLine() Show(BaseList, Environment.NewLine & "In Großbuchstaben") ' Und noch eine Zahlenreihe zum Abschluss NumberSequence.Present(AddressOf Predicates.Eleven, 1, 130) Console.ReadKey() End Sub ''' <summary> ''' Inhalt einer generischen Liste aus BaseSort-Objekten ausgeben ''' </summary> ''' <typeparam name="T">Welches Derivat von BaseSort?</typeparam> ''' <param name="List">Die Liste</param> ''' <param name="Str">Überschrift</param> Sub Show(Of T As BaseSort)(ByVal List As List(Of T), ByVal Str As String) Console.WriteLine("{0}:{1}", Str, Environment.NewLine) For Each b As BaseSort In List Console.WriteLine(b.Str) Next Console.WriteLine() Console.WriteLine() End Sub ''' <summary> ''' Klasse mit Prädikatfunktionen ''' </summary> ''' <remarks></remarks> Class Predicates ''' <summary> ''' Strings aus Auflistung entfernen ''' </summary> ''' <param name="obj">Das aktuelle Objekt</param> ''' <returns>Soll der String entfernt werden?</returns> Public Shared Function RemoveString(ByVal obj As BaseSort) As Boolean Return obj.Str.StartsWith("String") End Function ''' <summary> ''' Numerische Einträge finden ''' </summary> ''' <param name="obj">Das aktuelle Objekt</param> ''' <returns>Ist der Wert eine Zahl?</returns> Public Shared Function Numbers(ByVal obj As BaseSort) As Boolean Return IsNumeric(obj.Str) End Function ''' <summary> ''' String --> GROSSBUCHSTABEN ''' </summary> ''' <param name="obj">Das aktuelle Objekt</param> Public Shared Sub ToUCase(ByVal obj As BaseSort) obj.Str = obj.Str.ToUpper End Sub ''' <summary> ''' Ist ein Wert durch 11 teilbar? ''' </summary> ''' <param name="val">Wert</param> ''' <returns>Teilbar oder nicht</returns> Public Shared Function Eleven(ByVal val As Integer) As Boolean Return ((val Mod 11) = 0) End Function End Class ''' <summary> ''' Klasse für Nummernfolgen ''' </summary> ''' <remarks></remarks> Class NumberSequence ' Eigener Delegattyp - System.Predicate geht auch Public Delegate Function ValidEntry(ByVal Value As Integer) As Boolean ''' <summary> ''' Ausgeben ''' </summary> ''' <param name="Entries">Delegat für definierte Einträge</param> ''' <param name="From">Von</param> ''' <param name="To">Bis</param> Public Shared Sub Present(ByVal Entries As ValidEntry, Optional ByVal From As _ Integer = 0, Optional ByVal [To] As Integer = 100) Console.Write("Zahlenreihe von {0} bis {1} ausgeben: ", From, [To]) For i As Integer = From To [To] If Entries(i) Then Console.Write("{0}; ", i) Next End Sub End Class End Module End Namespace ' ------------------ Ende Datei Module1.vb ------------------ ' ----------- Ende Projektdatei Predicates.vbproj ----------- ' ------------ Ende Projektgruppe Predicates.sln ------------
Diskussion
Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.
Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.