Extension Problem... Sieht jemand warum?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von Artentus.

    Extension Problem... Sieht jemand warum?

    Hallo Leute und danke fürs reinschauen....

    mein Problem:
    Ich habe eine Extension:

    VB.NET-Quellcode

    1. <Extension()>
    2. Public Function ToInt(ByVal obj As Object, Optional ByVal def As Integer = 0) As Integer
    3. Try
    4. Return CInt(obj)
    5. Catch ex As Exception
    6. Return def
    7. End Try
    8. End Function


    Somit kann ich eine Variable converten... super.

    Hier noch ein Stück quellcode was nicht geht:

    VB.NET-Quellcode

    1. Dim xx As New Object
    2. Dim zz As Integer = 5
    3. Dim y = zz.ToInt(5)
    4. Dim u = xx.ToInt(5)


    also zz geht, xx geht nicht. Sieht einer warum?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „EugenIS“ ()

    Du machst mit der Variable "def" nix oO (EDIT: Jetzt doch)
    Der erste übergebene Parameter ist ja der Inhalt der aufrufenden Variable
    Bei xx währe es nix... Bei zz wäre es 5.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    Sorry, habe rum experementiert. Aber schon verbessert. jetzt mache ich mit def was....


    Aber eigentlich erstelle ich ja einen object der leer ist. das müsste dann auch gehen...

    Ich habe es auch an andren teilen, wie z. B. DataRowCell ausprobiert. Geht auch nicht. er macht nur dann was, wenn es auch ein Integer ist. Dann brauche ich auch kein converter... :(

    Wenn ich z. B. sagen würde dim x as object = "" dann würde mein object ein string ja sein. Aber die grundform ist immer noch ein object...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „EugenIS“ ()

    @EugenIS Machst Du Option Strict On, da hilft Dir bereits der Compiler.
    Was Du machen solltest, ist eine Shared Function:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim xx As New Object
    3. Dim yy = "77"
    4. Dim zz As Integer = 5
    5. Dim y = ToInt(zz)
    6. Dim x = ToInt(yy)
    7. Dim z = ToInt(xx)
    8. End Sub
    9. Private Shared Function ToInt(ByVal obj As Object) As Integer
    10. If TypeOf (obj) Is Integer Then ' kannst Du alles noch zusammenfassen
    11. Return CInt(obj)
    12. ElseIf TypeOf (obj) Is Long Then
    13. Return CInt(obj)
    14. ElseIf TypeOf (obj) Is String Then
    15. Return CInt(obj)
    16. End If
    17. Throw New ArgumentException
    18. End Function


    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!

    EugenIS schrieb:

    und eine Erweiterung
    Dein Codevorschlag ist Tinnef.
    Entweder Du willst den numerischen Wert vom aufrufenden Object haben oder den vom Parameter def.
    Beides macht da keinen Sinn.
    Sieh Dir mal an, was die MSDN zu Erweiterungsmethoden in VB sagt.
    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!
    Tinnef??? Wie bist du den drauf....

    ich wollte, wenn der irgend wie ein object nicht converten kann, soll er def nehmen. Guck doch mal in den ersten Post richtig rein.

    Zum andren, warum geht ToString() immer? Will ja nichts anderes haben...
    @EugenIS Sieh Dir mal dieses nicht funktionierende Beispiel an, das Dir das Problem verdeutlichen sollte:

    VB.NET-Quellcode

    1. Dim tb As Object = New TextBox
    2. Dim ii = tb.ToInt(42)
    3. MessageBox.Show(ii.ToString)
    Wozu brauchst Du eine Object-Variable, um einen Parameter zu konvertieren?
    =====

    Objektkatalog schrieb:

    Public Overridable Function ToString() As String
    Member von System.Object

    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!
    ToString ist eine Methode, die fast jede Klasse überschreibt, da sie per default nur den Klassennamen als String zurück gibt.
    Dein Beispiel ergibt nicht mal Sinn, es gibt doch int.TryParse(), was brauchst du mehr ?
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
    Die Bezeichnung 'ToString' ist auch ziemlich irreführend, da die Methode das Objekt nur für spezielle Fälle (Integers, Doubles) tatsächlich umwandelt. Für alle anderen Objekte gibt 'ToString' in erster Linie eine Beschreibung, die für den Menschen lesbar ist, zurück. Sobald eine Klasse von 'Object' erbt (und das tut sie letztendlich immer), besitzt sie auch die 'ToString'-Methode und kann diese überschreiben, um eine bessere Beschreibung des Objektes anbieten zu können.

    Nun musst du dir die Frage stellen, was du von deinem 'ToInt' erwartest. Was genau soll die Erweiterung zurückgeben? Für irgendeine Zahl vermutlich eben diese Zahl, für Gleitkommazahlen irgendwie gerundet. Was gibt sie für Zeichenketten zurück? Und da sie für alle Objekte gelten soll, was gibt sie für TextBoxen, TcpClients oder JsonConverter zurück? Vermutlich hast du für all diese Klassen keinen sinnvollen Anwendungszweck und solltest die Erweiterung daher auf die Datentypen beschränken, bei denen ein solcher Anwendungszweck gegeben ist.

    lukekogv schrieb:

    um eine bessere Beschreibung des Objektes anbieten zu können.
    der Instanz des Objektes.
    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!
    @lukekogv Beispiel Instanz der Klasse Rectangle, da stehen die konkreten Werte drin:

    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!
    Ja, ich weiß, daher schrieb ich auch 'Objekt' und nicht 'Klasse' ;)

    'Objekt' und 'Instanz' waren und sind für mich im Rahmen von OOP Synonyme, daher hat mich dein Einwand ein wenig aus dem Konzept gebracht und ich musste nochmal nachschauen, wo der Unterschied sein sollte.
    In VB.Net funktionieren Extensions nicht auf dem Typ Object, da der Compiler in diesem Fall Late Binding durchführt, was Extensions in die Quere kommt (was, wenn die aufgerufene Extension die selbe Signatur besitzt wie ein Member des Objekts).
    In C# funktioniert dies problemlos, da dort Late Binding über den dynamic-Typen implementiert ist.

    Das ist übrigens wieder ein Relikt aus VB6-Zeiten und einer der Gründe, warum C# die bessere Sprache ist.
    Also bis Artentus geschrieben hat, wusste ich nicht mal, was denn nicht funktionieren soll.
    Also @EugenIS : Hab ich aufgrund der Uhrzeit eine genaue Fehlerbeschreibung überlesen oder hast Du vergessen, zu erklären, was denn nicht funkioniert?

    Bezüglich des Problems mit Extensions auf Object: Das Problem hatte ich auch mal und das ist echt extrem doof: vb-paradise.de/index.php/Thread/?postID=838773#post838773
    Im Grunde genommen ist das ein nicht zu Ende gedachtes Feature, denn Code im Kontext von Option Strict On kann gar nie spät gebunden sein, also ist ein Aufruf einer Extension immer eindeutig. Hier wäre es sinnvoll, Aufrufe von Extensions nur dann nicht zu erlauben, wenn der Code im Kontext von Option Strict Off steht, aber sonst schon. Bravo, Microsoft.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Also noch einmal für die, die keinen Sinn und sonstiges in der Erweiterung sehen. Ich möchte einfach Einzeiler haben. Ich möchte nicht mit TryCarst und sonstigem arbeiten, da ich das mitten im Programm behandeln muss. So handle ich mit einer Zeile alles ab und habe das Verhalten immer gleich. Außerdem bleibt redundanter code weg. Das ist für die Experten, die kein Sinn usw. in meiner Erweiterung sehen. Für ein kleineres Programm braucht man natürlich so etwas nicht. Wenn das Programm größer wird, ist so etwas besser.

    Was das spätes binden angeht: Die Erweiterung gibt ein Int zurück. Somit ist es eigentlich kein spätes binden. Sondern der Typ ist direkt bekannt. Sonst müsste man ja jedes Dim x = "" in Frage stellen. Ist ja auch spätes Binden...
    Ich verstehe den Sinn auch durchaus.
    Die einzige Möglichkeit die mir einfällt ist eine .ToInt Extension nicht für Object zu erstellen, sondern für jeden Datentypen einzeln.
    So viele sollte es ja nun nicht geben die nen Int zurückgeben können, bzw. deren Inhalt in nen Int überhaupt umgesetzt werden könnte.
    String... Decimal... Double... Long... usw?!
    Denn du musst ja nicht ne Textbox.ToInt aufrufen... sondern eher TextBox.Text.ToInt (was nen String wäre)!?
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    Gott sei dank, da ist einer, der versteht was ich meine...

    Leider geht es auch nicht. Zum einem will ich es nicht nur für Int sondern ich will auch Long beispielsweise so konverten. Somit würde es alleine schon für primitive Datentypen sehr viele Erweiterungen ergeben. Die Arbeit würde ich mir sogar machen, aber ich möchte ab und zu auch wirklich ein Objekt konvertieren, von dem der Typ mir wirklich nicht bekannt ist, DAS KEIN PRIMITIVER TYP IST. Das ist mir eigentlich am wichtigsten nicht nur primitive Typen behandeln zu können. Sondern wirklich alles mögliche...
    Wie soll das denn gehen bei nem Object?
    Nen Object mit Namen Auto kann ja unterschiedlichste Datentypen GLEICHZEITIG enthalten...
    Name... String
    Geschwindigkeit... Decimal
    Farbe... Color
    usw.
    Welche soll denn so eine Erweiterung dann konvertieren?
    Auto.Geschwindigkeit.ToInt würde ja gehen.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D