Override String.Contains

  • VB.NET

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von Jan123456.

    Override String.Contains

    Hallo Leute,

    kann mir jemand beim Überschreiben der String.Contains Methode helfen? Ich will Contains so abändern, dass es case insensitive ist.
    Ich habe folgendes für c# gefunden, bekomme es aber nicht für VB hin: stackoverflow.com/questions/44…nsensitive-containsstring

    Folgenden Ansatz habe ich, dabei kommt allerdings ein Compiler-Fehler mit dem ich nichts anfange:
    - function "Contains" kann nicht als "Overrides" deklariert werden, da es function in Basis class nicht überschreibt. -


    VB.NET-Quellcode

    1. Imports System
    2. Public Class StringManager
    3. Public Overrides Function Contains() As Boolean
    4. End Function
    5. End Class
    Willkommen im Forum. :thumbup:
    Sieh Dir mal Befehlserweiterung an.

    VB.NET-Quellcode

    1. Imports System.Runtime.CompilerServices
    2. ' Modul, Sub
    3. Module StringExtensions
    4. <Extension()> _
    5. Public Sub Print(ByVal txt As String)
    6. Console.WriteLine(txt)
    7. End Sub
    8. End Module
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wieso nicht einfach vorher den Text auf ToLower ändern?
    Wobei ich eine String.Contains("Text", Case) nicht schlecht fände ^^
    "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

    Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!

    VB.NET-Quellcode

    1. <System.Runtime.CompilerServices.Extension()> _
    2. Public Function ContainsExt(ByVal s As String, ByVal value As String, ByVal CaseSensetiv As Boolean) As Boolean
    3. If CaseSensetiv Then
    4. Return s.Contains(value)
    5. Else
    6. Return s.ToLower.Contains(value.ToLower)
    7. End If
    8. End Function


    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    @fichz:

    Er will die Contains-Methode überschreiben.
    Grüße
    "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

    Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!
    @Nikx:
    Schon klar, nur ist die Contains Methode leider nicht als Überschreibbar gekennzeichnet.
    Deswegen kann man sich eine Extension basteln welche bei allen Strings unter "Contains" aufscheint.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten

    Jan123456 schrieb:

    kann mir jemand beim Überschreiben der String.Contains Methode helfen?
    nein, das kann niemand, denn String ist NotInheritable.
    scheinbar fehlen dir nicht unwesentliche Grundlagen, nämlich, was Überschreiben bedeutet, und vmtl. auch, was NotInheritable bedeutet.

    Da das miteinander zusammenhängt (und mit einigem weiteren) und da es erschöpfend zu behandeln hier zu weit führen würde (und unsere Erklärungen zu schlechte Qualität hätten) empfehle ich dieses Buch lesen (hingegen das Galileio-Openbook ist Mist)

    VB.NET-Quellcode

    1. Public NotInheritable Class Enumerable

    "NotInheritable gibt an, dass eine Klasse nicht als Basisklasse verwendet werden kann."

    Ok, kapiert, überschreiben kann ich sie nicht. Kann ich sie dann überladen?

    Mein Problem ist, dass ich die Contains-Methode öfters in einem Programm verwendet habe, und mich nicht um Groß- und Kleinschreibung gekümmert hab. Am Anfang wars noch egal, aber jetzt bereu ich es :D
    Ich such halt einen einfachen Weg das wieder zu korrigieren ohne jedes Contains im Quellcode zu suchen.
    Strg+Shift+F ... :D
    Dort bei Replace dann einfach .Contains( eingeben und untendrunter .ToLower.Contains( eingeben, und dich dann dort durch klicken. Ist keine große Angelegenheit und geht recht schnell ;)
    Ich schreibe keine Funktion, um meine Fehler bedeutungslos zu machen, sondern um sie zu korrigieren, was damit aber nicht der Fall ist.

    OK, in dem Fall wäre es tatsächlich lohnenswert nen entsprechenden Overload zu haben (Aber auch wirklich Overload, ich will nicht gezwungen werden das Casing angeben zu müssen).
    Versuch doch einfach mal nen Overload zu deklarieren, vielleicht gehts, vielleicht nicht. Habs Studio grad net auf und weiß es net ^^
    Du kannst dir eine Extension schreiben, die intern mit IndexOf arbeitet, wie in post#6 angedeutet.
    Vorraussetzung dafür ist, dass du es kannst, also dass dir die OOP-Grundlagen bekannt sind, zuzüglich die Funktionsweise von Extension-Methods. Und dass du den ObjectBrowser/ObjektKatalog bedienen kannst, um die genannte Überladung auch zu recherchieren.
    Also dieses Buch lesen (hingegen das Galileio-Openbook ist Mist)
    Zur Info, wie ist .Contains implementiert?

    Quellcode

    1. [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    2. public bool Contains(string value)
    3. {
    4. return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
    5. }


    :thumbsup:

    fichz schrieb:

    Wie findet man so eine Implemention heraus?

    Cursor auf die Methode und dann F12.

    Ach ja ... und es hilft unheimlich, wenn der .Net Reflector installiert ist ;)
    Alternativ zb ILSpy o.ä. Weiß aber nicht, wie die in die IDE integriert sind. Ich finds halt mit Reflector deutlich bequemer und es ist ja nicht SO teuer (relativ halt)
    Gelöst mit Hilfe einer Extension. Danke für die Hilfe an euch...

    VB.NET-Quellcode

    1. Imports System.Runtime.CompilerServices
    2. Public Module ClassLibraryModule
    3. <Extension()> Public Function contains(ByVal original_string As String, ByVal search_string As String, ByVal compare_type As StringComparison) As Boolean
    4. If original_string.IndexOf(search_string, compare_type) >= 0 Then
    5. Return True
    6. Else
    7. Return False
    8. End If
    9. End Function
    10. End Module


    So habe ich dann darauf zugegriffen:

    VB.NET-Quellcode

    1. Dim str As String = "TEST"
    2. If str.contains("test", StringComparison.OrdinalIgnoreCase) Then
    3. MsgBox("yes")
    4. Else
    5. MsgBox("no")
    6. End If



    Ich musste zwar trotzdem noch jedes Contains im Quellcode suchen und die StringComparison hinzufügen, aber da hat glaube ich auch kein Weg vorbei geführt.


    Ich verstehe allerdings nicht so ganz, wie der Original-String (also in dem Beispiel das TEST) an die Extension Funktion übergeben wird. Kann mir das jemand erklären?
    Und woher weiß VB, dass es eine Extension für Strings ist?
    Welchen Typ hat der Ausdruck (original_string.IndexOf(...) >= 0) ?
    Und welchen Rückgabe-Typ hat Deine Funktion?

    (Tipp: Es ist Boolean)

    Du prüfst also den Ausdruck und gibst True bei True und False bei False zurück. Klingelt's da bei Dir, wenn Du den Code (speziell die Return-Anweisungen) anschaust?
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Das hier "reicht":

    VB.NET-Quellcode

    1. Public Module StringExtensions
    2. <System.Runtime.CompilerServices.Extension()>
    3. Public Function ContainsCase(ByVal original_string As String, ByVal search_string As String, Optional ByVal compare_type As StringComparison = StringComparison.OrdinalIgnoreCase) As Boolean
    4. Return original_string.IndexOf(search_string, compare_type) >= 0
    5. End Function
    6. End Module
    Dadurch, dass der Parameter compare_type als Optional gekennzeichnet ist, muss man kein Casing angeben. ist das der Fall, wird OrdinalIgnoreCase verwendet.

    Jan123456 schrieb:

    Und woher weiß VB, dass es eine Extension für Strings ist?
    VB nimmt den ersten Parameter. Da dieser vom Typ String ist, weiß er, dass es ein String ist. IN C# wird es mit dem this-Schlüsselwort gekennzeichnet.

    picoflop schrieb:

    Cursor auf die Methode und dann F12.
    [...]
    Alternativ zb ILSpy o.ä. Weiß aber nicht, wie die in die IDE integriert sind. Ich finds halt mit Reflector deutlich bequemer und es ist ja nicht SO teuer (relativ halt)
    Wie wäre es, wenn man sich stattdessen den Reference Source Code des Frameworks in Visual Studio einträgt? Ja, .NET ist "im Prinzip" OpenSource, was nicht viele wissen. Man darf den Quelltext aber nur zu Debugging-Zwecken verwenden (laut Wikipedia).
    Den .NET-Sourcecode gibt's hier:
    referencesource.microsoft.com/netframework.aspx (Lizenz beachten!)

    So stellt man Visual Studio dann ein:
    referencesource.microsoft.com/serversetup.aspx
    Fertig. Und das ganz ohne Reflector. ;)

    Zum Quelltext:
    Man muss ein bisschen mit dem Entpacken spielen - 7Zip kann das alles. In der Datei "source" befindet sich dann der gesamte Quelltext als text. Einfech mal mit 'nem Texteditor öffnen.
    Von meinem iPhone gesendet

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „nikeee13“ ()

    nikeee13 schrieb:


    Jan123456 schrieb:

    Und woher weiß VB, dass es eine Extension für Strings ist?
    VB nimmt den ersten Parameter. Da dieser vom Typ String ist, weiß er, dass es ein String ist. IN C# wird es mit dem this-Schlüsselwort gekennzeichnet.

    Verstanden, danke :)


    Jetzt hätte ich nur noch eine letzte Frage 8-)
    Ich habe jetzt das "original" contains:

    VB.NET-Quellcode

    1. Public Function Contains(ByVal value As String) As Boolean

    Und meine gleich benannte Extension:

    VB.NET-Quellcode

    1. <Extension()> Public Function contains(ByVal original_string As String, ByVal search_string As String, Optional ByVal compare_type As StringComparison = StringComparison.OrdinalIgnoreCase) As Boolean


    D.h. beides mal eine Contains-Methode mit nur einem String als Übergabewert. In dem Fall wird automatisch die Extension genommen, richtig? Auf dem Weg hätte ich Contains ja "überschrieben", was ja mein ursprüngliches Ziel war. Oder spricht irgendwas dagegen, das so zu machen?