Die Community zu .NET und Classic VB.
Menü

Tipp-Upload: VB.NET 0139: Predicates für Listen verwenden

 von 

Ü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.

Zurück zur Übersicht

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

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

Download:

Download des Beispielprojektes [9,26 KB]

' 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.