Instanzen vergleichen mit eigener Methode

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

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Instanzen vergleichen mit eigener Methode

    Hallo,

    ich habe eine Klasse deren Instanzen ich in List(Of )s sammle. Jetzt würde ich gerne in der Klasse festlegen, wann eine Instanz einer anderen gleicht, sodass ich in meiner Liste herausfinden kann, ob mehrere gleiche Elemente enthalten sind.
    Wie muss man sowas umsetzen?

    In der Enumerable.Distinct Methode gibt es eine Überladung, die mir so aussieht als könnte man dort eigene Kriterien festlegen, nur hab ich das mit der IEqualityComparer Schnittstelle noch nicht begriffen. Der dort angegebene "comparer" könnte der ein Bestandteil der Klasse werden oder muss das ein separates Objekt sein?

    Edit:
    Pseudo

    VB.NET-Quellcode

    1. Friend Class Oberklasse
    2. Friend Property Zuordnung
    3. Sub New(input)
    4. SetZuordnung(input)
    5. End Sub
    6. Friend Function IchbindieseInstanz As ???
    7. ???
    8. End Function
    9. End Class
    10. Friend Class Zuordnung
    11. Friend Property Länge As Single
    12. Friend Property Breite As Single
    13. Friend Property Typ As String
    14. End Class
    15. Sub Main
    16. Dim lst as New List(Of Oberklasse)
    17. lst.Add(New Oberklasse(input1))
    18. lst.Add(New Oberklasse(input2))
    19. Console.Writeline((lst.Count = lst.SpecialDistinct.Count).ToString)
    20. End Sub



    Viele Grüße

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

    Hallo,
    der mMn bessere Weg ist, deine Klasse implementiert IEquatable<T>, IComparable und IComparable<T>. Damit kannst du a) deine Kriterien einfach festlegen, wann ein Objekt gleich ist und b) so ganz leicht IEnumerable.Distinct verwenden.
    Beispiel:
    Achtun, ich habe den Code von C# nach VB umgewandelt. Keine Garantie, dass der so direkt funktioniert.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. ​Friend Class MyT
    2. Implements IEquatable(Of MyT), IComparable, IComparable(Of MyT)
    3. Public Property Width As Integer
    4. Public Property Height As Integer
    5. Public Function CompareTo(ByVal other As MyT) As Integer
    6. If other Is Nothing Then
    7. Return 1
    8. End If
    9. If Width <> other.Width Then
    10. If Width > other.Width Then
    11. Return 1
    12. Else
    13. Return -1
    14. End If
    15. End If
    16. If Height <> other.Height Then
    17. If Height > other.Height Then
    18. Return 1
    19. Else
    20. Return -1
    21. End If
    22. End If
    23. Return 0
    24. End Function
    25. Public Function CompareTo(ByVal obj As Object) As Integer
    26. If obj Is Nothing Then
    27. Return 1
    28. End If
    29. Dim other As MyT = TryCast(obj, MyT)
    30. If other Is Nothing Then
    31. Return 1
    32. End If
    33. If Width <> other.Width Then
    34. If Width > other.Width Then
    35. Return 1
    36. Else
    37. Return -1
    38. End If
    39. End If
    40. If Height <> other.Height Then
    41. If Height > other.Height Then
    42. Return 1
    43. Else
    44. Return -1
    45. End If
    46. End If
    47. Return 0
    48. End Function
    49. Public Overloads Function Equals(ByVal other As MyT) As Boolean
    50. If other Is Nothing Then Return False
    51. If Width <> other.Width OrElse Height <> other.Height Then Return False
    52. Return True
    53. End Function
    54. Public Overrides Function Equals(ByVal obj As Object) As Boolean
    55. Dim other As MyT = TryCast(obj, MyT)
    56. If other Is Nothing Then
    57. Return False
    58. End If
    59. If Width <> other.Width OrElse Height <> other.Height Then Return False
    60. Return True
    61. End Function
    62. Public Overrides Function GetHashCode() As Integer
    63. Dim accumulator = 0
    64. accumulator = accumulator Or (Width And &H0000000F) << 28
    65. accumulator = accumulator Or (Height And &H000000FF) << 20
    66. Return accumulator
    67. End Function
    68. End Class



    Spoiler anzeigen

    VB.NET-Quellcode

    1. ​Dim l As List(Of MyT) = New List(Of MyT)()
    2. l.Add(New MyT() With {
    3. .Width = 1,
    4. .Height = 2
    5. })
    6. l.Add(New MyT() With {
    7. .Width = 1,
    8. .Height = 2
    9. })
    10. l.Add(New MyT() With {
    11. .Width = 4,
    12. .Height = 2
    13. })
    14. l.Add(New MyT() With {
    15. .Width = 2,
    16. .Height = 3
    17. })
    18. l.Add(New MyT() With {
    19. .Width = 6,
    20. .Height = 2
    21. })
    22. Dim distinctList = l.Distinct()

    Ich weiß ja nicht, wie Du das konkret einsetzen willst, aber die gewünschte Funktion IchbindieseInstanz ließe sich so machen:

    VB.NET-Quellcode

    1. Friend Function IchbindieseInstanz(Oberklasseninstanz As Oberklasse) As Boolean
    2. Return Me Is Oberklasseninstanz
    3. End Function

    ->

    VB.NET-Quellcode

    1. Dim Oberklasseninstanz1 As New Oberklasseninstanz
    2. Dim Oberklasseninstanz2 As New Oberklasseninstanz
    3. MessageBox.Show(Oberklasseninstanz1.IchbindieseInstanz(Oberklasseninstanz1).ToString)
    4. MessageBox.Show(Oberklasseninstanz1.IchbindieseInstanz(Oberklasseninstanz2).ToString)
    5. MessageBox.Show(Oberklasseninstanz2.IchbindieseInstanz(Oberklasseninstanz1).ToString)
    6. MessageBox.Show(Oberklasseninstanz2.IchbindieseInstanz(Oberklasseninstanz2).ToString)


    Ansonsten reicht ggf auch schon das Überladen der entsprechenden Operatoren:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Friend Class FrmMain
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim Foo1 As Foo = Nothing
    4. Dim Foo2 As Foo = Nothing
    5. If Foo1 = Foo2 Then Stop 'stoppt
    6. Foo1 = New Foo
    7. If Foo1 = Foo2 Then Stop
    8. Foo2 = New Foo
    9. If Foo1 = Foo2 Then Stop 'stoppt
    10. Foo1.Bar = "asd"
    11. If Foo1 = Foo2 Then Stop
    12. Foo2.Bar = "asd"
    13. If Foo1 = Foo2 Then Stop 'stoppt
    14. End Sub
    15. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    16. Dim Foo1 As Foo = Nothing
    17. Dim Foo2 As Foo = Nothing
    18. If Foo1 <> Foo2 Then Stop
    19. Foo1 = New Foo
    20. If Foo1 <> Foo2 Then Stop 'stoppt
    21. Foo2 = New Foo
    22. If Foo1 <> Foo2 Then Stop
    23. Foo1.Bar = "asd"
    24. If Foo1 <> Foo2 Then Stop 'stoppt
    25. Foo2.Bar = "asd"
    26. If Foo1 <> Foo2 Then Stop
    27. End Sub
    28. End Class
    29. Friend Class Foo
    30. Property Bar As String
    31. Public Overloads Shared Operator =(F1 As Foo, F2 As Foo) As Boolean
    32. If F1 Is Nothing AndAlso F2 Is Nothing Then Return True
    33. If F1 Is Nothing OrElse F2 Is Nothing Then Return False
    34. Return F1.Bar = F2.Bar
    35. End Operator
    36. Public Overloads Shared Operator <>(F1 As Foo, F2 As Foo) As Boolean
    37. Return Not F1 = F2
    38. End Operator
    39. End Class


    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Haudruferzappeltnoch Wenn Du Instanzen von Klassen vergleichen willst, bau Dir eine Klasse, wie sie von @ISliceUrPanties vorgeschlagen wurde.
    Ich hab sie mal etwas getunt:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class MyT
    2. Implements IEquatable(Of MyT), IComparable, IComparable(Of MyT)
    3. Public Property Width As Integer
    4. Public Property Height As Integer
    5. Public Function Equals(other As MyT) As Boolean Implements IEquatable(Of MyT).Equals
    6. If other Is Nothing Then Return False
    7. Return Width = other.Width AndAlso Height = other.Height
    8. End Function
    9. Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
    10. Dim other As MyT = TryCast(obj, MyT)
    11. Return Me.CompareTo(other)
    12. End Function
    13. Public Function CompareTo(other As MyT) As Integer Implements IComparable(Of MyT).CompareTo
    14. If other Is Nothing Then
    15. Return 1
    16. End If
    17. If Width <> other.Width Then
    18. Return Width.CompareTo(other.Width)
    19. End If
    20. If Height <> other.Height Then
    21. Return Height.CompareTo(other.Height)
    22. End If
    23. Return 0
    24. End Function
    25. End Class
    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!
    Kommt immer drauf an was man will.
    Wenn man richtig wasserdicht, komfortabel und ohne Überraschungen vergleichbarkeit implementieren will, muss man IComparable, IComparable(Of T), IEquatable, IEquatable(Of T) implementieren, und zusätzlich die Operatoren <, >, <>, =, >=, <= überladen.
    Und Gethashcode() überschreiben, damit Gleichheit auch in einem Dictionary richtig festgestellt wird.
    Ehrlich gesagt, ich back da lieber kleinere Brötchen, und sortiere und vergleiche einfach mit einer Comparison(Of T). Sone Comparison kann man auch Shared iwo statisch bereitstellen, dass das einfürallemal geklärt ist.
    Hat den Vorteil, dass man auch andere Comparison(Of T) definieren kann, und dann sortierts halt anders.
    Ja das ich mir da eine Schnittstelle reinholen muss habe ich schon gedacht. Ich arbeite mich da mal rein. Meine Funktion ist in der Hinsicht Käse gewesen.
    Das Überschreiben der Operatoren verstehe ich; wenn jemand einen Vergleich machen möchte ist ja nicht unbedingt klar, was er benutzt.
    Ich benötige in dem Sinne noch keine umfangreiche Vergleichbarkeit, mir reicht es wenn List(Of MyClass).Distinct nach anderen Regeln funktioniert.(Dafür brauchts ja eventuell doch umfangreiche Vergleichbarkeit)

    Die IEquatable ohne (Of T) finde ich gar nicht. Den Unterschied zwischen IComparable und IComparable(Of T) verstehe ich nicht ganz. IComparable ist zum vergleichen mit allem Möglichem IComparable(Of T) zum Vergleich zwischen T-Instanzen? Aber im Beispiel von IComparable wird das Vergleichsobjekt einfach versucht auf T zu casten. Ab dem Punkt ist es ja dasselbe, ich schätze das ist relevant für Vererbung.

    Ich schätze mal Distinct sortiert vorher für die Effizienz und braucht daher IComparable? Ich hab es mal versucht nach meinen Verständnis nachzubilden, allerdings funktioniert es noch nicht, ich übersehe noch etwas.
    Edit: Mit eigenem Loop funktionierts

    Versuch

    VB.NET-Quellcode

    1. Friend Class Oberklasse
    2. Implements IEquatable(Of Oberklasse)
    3. Implements IComparable(Of Oberklasse)
    4. Implements IComparable
    5. Friend Property ZuOrd As Zuordnung
    6. Sub New(length As Single, width As Single, kind As String)
    7. ZuOrd = New Zuordnung With {.Länge = length, .Breite = width, .Typ = kind}
    8. End Sub
    9. Public Overloads Function Equals(other As Oberklasse) As Boolean Implements IEquatable(Of Oberklasse).Equals
    10. If other Is Nothing Then Return False
    11. Dim tolerance As Single = 5.0
    12. Return Math.Abs(ZuOrd.Länge - other.ZuOrd.Länge) < tolerance AndAlso Math.Abs(ZuOrd.Breite - other.ZuOrd.Breite) < tolerance AndAlso ZuOrd.Typ <> other.ZuOrd.Typ
    13. End Function
    14. Public Overrides Function Equals(other As Object) As Boolean
    15. Return False
    16. End Function
    17. Public Function CompareTo(other As Oberklasse) As Integer Implements IComparable(Of Oberklasse).CompareTo
    18. If other Is Nothing Then Return 1
    19. If Me.Equals(other) Then
    20. Return 0
    21. Else
    22. Dim a = ZuOrd.Länge - other.ZuOrd.Länge
    23. If a > Zuordnung.tolerance Then
    24. Return 1
    25. ElseIf a < -Zuordnung.tolerance Then
    26. Return -1
    27. Else
    28. Dim b = ZuOrd.Breite - other.ZuOrd.Breite
    29. If b > Zuordnung.tolerance Then
    30. Return 1
    31. ElseIf b < -Zuordnung.tolerance Then
    32. Return -1
    33. Else
    34. Return 0 'Gleiche Größen, gleicher Typ
    35. End If
    36. End If
    37. End If
    38. End Function
    39. Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
    40. Return 1
    41. End Function
    42. End Class
    43. Friend Class Zuordnung
    44. Friend Property Länge As Single
    45. Friend Property Breite As Single
    46. Friend Property Typ As String
    47. End Class
    48. Sub Main()
    49. Dim lst As New List(Of Oberklasse)
    50. lst.Add(New Oberklasse(50.0, 49.9, "a"))
    51. lst.Add(New Oberklasse(50.0, 50.0, "b"))
    52. lst.Sort()
    53. Dim test As Boolean = True
    54. For i = 0 To lst.Count - 2
    55. If lst(i).Equals(lst(i + 1)) Then test = False : Exit For
    56. Next
    57. Console.WriteLine(test.ToString)
    58. Console.ReadKey()
    59. End Sub

    Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    IEquatable gibt's auch nicht untypisiert, also ohne Of T.

    Haudruferzappeltnoch schrieb:

    IComparable ist zum vergleichen mit allem Möglichem IComparable(Of T) zum Vergleich zwischen T-Instanzen
    richtig; Da ältere Konstrukte vor Einführung von Generika (also mit diesem Of T) existierten und die auch Dinge vergleichen woll(t)en, gab es da nur die untypisierte Object-Variante. Die Of T-Varianten machen den Umgang leichter, kamen allerdings eben erst später.

    Haudruferzappeltnoch schrieb:

    im Beispiel von IComparable wird das Vergleichsobjekt einfach versucht auf T zu casten. Ab dem Punkt ist es ja dasselbe
    Genau. Der alte Rumpf wird genommen und zu dem neuen Kram kompatibel gemacht. Mit Vererbung hat das jetzt weniger zu tun als mit Abwärtskompatibilität.

    Wenn Du tiefergreifende/fortgeschrittene Vergleiche machen willst/wirst, solltest Du Dich weiter damit beschäftigen. Aber Dein Codebeispiel würde ich noch mit einer einfachen, "manuellen" Funktion umsetzen (also so, wie Du selbst vorgeschlagen hast) und gar nicht mit Distinct arbeiten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ja ich habe es gerade probiert. Habe oben das Distinct ersetzt, so funktioniert es schon.

    Nachtrag: Eine Frage hätte ich noch

    VB.NET-Quellcode

    1. Public Overloads Function Equals(other As Oberklasse) As Boolean Implements IEquatable(Of Oberklasse).Equals
    2. End Function

    Wenn ich hier das Overloads weglasse sagt mir das Studio die Funktion führt Shadowing durch und empfiehlt Overrides. Mit Overrides sagt das Studio es gibt keine Funktion die überschrieben werden kann. Das klingt widersprüchig, was bedeutet das?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Haudruferzappeltnoch schrieb:

    Ja das ich mir da eine Schnittstelle reinholen muss habe ich schon gedacht.
    Was ich sage ist aber das Gegenteil:
    Sortieren, insbesondere Sortieren nach beliebigen Kriterien, geht viel einfacher ohne dieses Schnittstellen-Gehampel - einfach einer List(Of T).Sort() - Überladung eine Comparison mitgeben, dann sortiert sie unter Anwendung der angegebenen VergleichsRegel.
    Geht natürlich nicht immer. Bei Dingen aus der Steinzeit (DatagridViewSorter) muss man leider tun, was da an Umständlichkeiten verlangt ist.
    Oder man verwendet DGV datengebunden - dann kann man über bindingSource.Sort sortieren.
    Du hast ja nicht nur vom Comparison geredet.
    Ja das ist schon einfacher. Für mich hat das zu sortierende Objekt eine Eigenschaft, die es als sortierbar auszeichnet. Ich fand die Schnittstelle ist vom Modell da schonmal nah dran.

    Aber sortieren reicht mir ja nicht (Die Sortierung macht nur den Prozess, den ich benötige effizienter), also die IEquatable Schnittstelle brauche ich in jedem Fall, weil es einen Fall gibt in dem der Comparer nicht entscheiden kann welches Element größer oder kleiner ist, sie sind nur nicht gleich. Das ist ganz ähnlich mit komplexen Zahlen, die haben keine Anordnung, können sich aber unterscheiden.

    Haudruferzappeltnoch schrieb:

    sie sind nur nicht gleich.
    Meinst Du, dass zwei Instanzen derselben Klasse mit gleichem Inhalt als verschieden erkannt werden sollen?

    VB.NET-Quellcode

    1. Dim a = New WhatEver(1, 2, 3)
    2. Dim b = New WhatEver(1, 2, 3)
    3. If a.Equals(b) Then
    4. MessageBox("Gleich")
    5. Else
    6. MessageBox("nicht Gleich")
    7. End If
    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!

    Haudruferzappeltnoch schrieb:

    weil es einen Fall gibt in dem der Comparer nicht entscheiden kann welches Element größer oder kleiner ist
    Verstehe ich nicht.
    wenn ein Comparer comparen kann, dann ist damit auch ein Gleichheits-Zustand definiert.
    Nämlich wenn die Compare-methode 0 return.
    Achso - sorry: er kann ja nicht Comparen. (komischer comparer)
    Ja ok. Also ich habe Element A und Element B.
    Der Comparer hat also die Möglichkeit A>B return 1, A<B return -1, A=B return 0

    In meinem Fall gibt es aber auch noch A<>B (Keins der obigen). Dann gibts auch 0. Und ich suche eine 0, aber welche 0 ist die richtige?
    Man muss hier das Ziel berücksichtigen, dass ein Comparer nicht compared hab ich nicht gesagt.
    Nein, dann ist die Compare-Verwendung aber unsinnig. Ungleich ist so ziemlich vieles. Nämlich alles, was nicht gleich ist. Bedenke, worum es geht: Sortierung. Wenn Du zwei Dinge sortieren sollst, die einfach "ungleich" sind, aber weder A > B noch A < B, und Dein Chef von Dir verlangt, dass Du die trotzdem sortieren sollst, wie willst Du dann entscheiden, was zuerst kommt? Was bedeutet denn in Deinem Fall "ungleich"? Zwei verschiedene Objekte? Also irgendwas stimmt da noch nicht vom Ablauf.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Nein es stimmt alles. Das ist ja der Punkt^^
    Mein Problem ist gelöst und ich wollte nur mitteilen warum ich es nicht nur mit einer Comparison lösen konnte, ich hab es ja versucht. Da wie Edr schon sagte das die einfachere Lösung ist.

    Sortieren ist fein was die Elemente angeht die tatsächlich größer oder kleiner sind. Für die anderen Elemente brauche ich keine Sortierung, diese müssen nur "entdeckt" werden. Die Sortierung hilft das Entdecken effizienter zu machen, es geht auch ganz ohne sortieren.
    Ich frage mich jetzt gerade, ob man das nicht auch mit einer Binary-Serialisierung hingekriegt hätte.
    Sind zwei Instanzen gleich sollte auch die gleiche Bytefolge entstehen.

    Wenn aber da zuerst irgendwelche Sachen sortiert werden müssen, dann wird es wahrscheinlich nicht gehen.

    Freundliche Grüsse

    exc-jdbi
    Ich kenn den Artikel.

    Ich finde es ein bisschen schade, dass die Binary-Serialisierung obsolate wird. Klar, wenn eine Binary-Serialisierung falsch angewendet wird, dann ist es gefährlich. Leider wird nicht genau beschrieben in der Dokumentation wie das gemeint ist.
    Net Standard hat vermutlich ganz neue Ansichten und hoch optimierte Möglichkeiten der strukturierten Daten auf sequenzielle Darstellungsform hervorgebracht.

    Als Alternative für die Binary-Serialisierung gibt es den DataContract-Serialisierer und XmlDictionaryWriter.CreateBinaryWriter(stream) bietet eine Binary-Version an. Die ist aber nicht direkt vergleichbar mit dem Binary-Formatter.

    Eine weitere Möglichkeit die ich gefunden habe, ist die MessagePack, eine sehr performante die gleichzeitig eine sehr kurze Bytefolge ausgibt. Und natürlich gibt es noch den Json-Serialisierer.

    Alle 3 Serialisierer sind schnell, und erfüllen in dem Sinne den Zweck der Serialisierung. Ob die für den Vergleich von Objekten herangezogen werden können müsste man zuerst ausprobieren.

    EDIT: Zuordnung.tolerance habe ich nicht gesehen. Da wäre die Lösung #6 wohl die beste vorgehensweise.

    Freundliche Grüsse

    exc-jdbi

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „exc-jdbi“ ()

    Ich glaube nicht, dass das mit BinarySerialisierung überhaupt geht. Ich hatte das früher mal versucht, aber zwei Klasseninstanzen mit identischen Daten wurden (zurecht) als unterschiedliche Objekte betrachtet, daher flog das für mich raus. XML-Serialisierung flog für mich raus, weil ich da überall das <Serializable>-Attribut setzen musste. Oder war das beim Binary? Na wurscht, irgendwas hat mich ja eben auch genervt. Daher bin ich sehr zufrieden beim NewtonSoft-JSON-Serializer geblieben, den kann ich so einstellen, wie ich ihn brauche und kann dann sehr einfach die Daten vergleichen und mir (fast alle) Unterschiede anzeigen lassen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.