Generika

  • VB.NET

Es gibt 53 Antworten in diesem Thema. Der letzte Beitrag () ist von RushDen.

    Hätte mal eine Frage zu Generika - ob ich das richtig verstanden hab:

    Also Generika benutzt man, wenn man die selbe Prozedur/Funktion mit verschiedenen Datentypen durchführen möchte, z.B.:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private newKlasse As New Klasse(Of String)
    3. Private neuklasse As New Klasse(Of Integer)
    4. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    5. MessageBox.Show(newKlasse.zählen("Hallo"))
    6. MessageBox.Show(neuklasse.zählen(5))
    7. End Sub
    8. End Class
    9. Public Class Klasse(Of Data)
    10. Public Function zählen(ByVal item As Data) As Data
    11. Dim tempitem As Data = item
    12. Return tempitem
    13. End Function
    14. End Class


    Dadurch braucht man nicht mehrere Prozeduren/Funktionen wie hier;

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private zählung As New Data
    3. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    4. MessageBox.Show(zählung.zählen(5))
    5. MessageBox.Show(zählung.zählen("Hallo"))
    6. End Sub
    7. End Class
    8. Public Class Data
    9. Public Overloads Function zählen(ByVal item As Integer) As Integer
    10. Dim tempitem As Integer = item
    11. Return tempitem
    12. End Function
    13. Public Overloads Function zählen(ByVal item As String) As String
    14. Dim tempitem As String = item
    15. Return tempitem
    16. End Function
    17. End Class


    sondern nur eine.

    Ist das so richtig? Wenn nicht kann mir das einer nochmal erklären?
    Hi
    quasi, denke ich. Die Beschreibung ist etwas dürftig formuliert.
    Generika sind Platzhalter für Typen:

    VB.NET-Quellcode

    1. Public MustInherit Class X(Of TGeneric)
    2. Implements IEnumerable(Of TGeneric)
    3. '...
    4. End Class
    5. Public Class Y(Of TBase)
    6. Public Function GetValue(Of T As TBase)() As T
    7. 'Do something
    8. End Function
    9. End Class


    Der Platzhalter wird dann eben durch die Angabe des generischen Arguments mit dem Typ ersetzt, den du im Argument angegeben hast. Das 2. Beispiel zeigt eine Typ-Einschränkung. Man kann auch mehrere Einschränkungen definieren:

    VB.NET-Quellcode

    1. Public Class Z(Of TBase, T As {TBase, IEnumerable(Of TBase), New})

    Das 2. generische Argument muss dann eben TBase und IEnumerable(Of TBase) sein, sowie über einen parameterlosen Konstruktor verfügen.
    Stelle es dir wirklich als Platzhalter vor, das dann eben ausgetauscht werden kann.
    Man kann btw. auch nur eine Basisklasse definieren, die restlichen Typeinschränkungen müssen Interfaces sein, da man eben nur von einer Klasse direkt erben kann.

    Gruß
    ~blaze~
    Ah, also der Datentyp ist dann variabel und wird halt bei der Instanzierung festgelegt und je nachdem welcher Datentyp dann bei der Instanzierung angegeben wurde, werden die Funktionen / Methoden / ... mit dem angegebenen Datentyp durchgeführt (natürlich nur wenn man den als parameter hat).
    Also ein Platzhalter wie du gesagt hast..
    kleiner Test: folgendes Modul mit einer Extension-Function, als Verbesserung der ICloneable-Schnittstelle:

    VB.NET-Quellcode

    1. Imports System.Runtime.CompilerServices
    2. Module Extensions
    3. <Extension(), DebuggerStepThrough()> _
    4. Public Function CloneX(Of T As ICloneable)(ByVal Obj As T) As T
    5. Return DirectCast(Obj.Clone(), T)
    6. End Function
    7. End Module
    Folgende Nutzung dieser Methode, im Vergleich zum ollen .Clone()

    VB.NET-Quellcode

    1. Public Sub Main()
    2. Dim arr = Enumerable.Range(2, 3).ToArray
    3. Dim o = arr.Clone
    4. Dim a = arr.CloneX
    5. End Sub
    Welchen Datentyp hat arr, o, a?
    also o ist Object weil .clone ein object zurückgibt
    Ich versteh aber nicht wofür das hier ist;

    VB.NET-Quellcode

    1. <Extension(), DebuggerStepThrough()> _


    Sonst glaub ich, weil CloneX ja das gleiche tut wie .Clone nur das er kein Object sondern den Datentypen des jeweiligen Arrays(also arr) von dem eine Kopie erstellt wird,
    dass a = integer ist und arr halt auch integer weil enumerable.range(2,3).toarray sind ja 2 Zahlen (Integer) die generiert werden und das wird dann in ein Array umgewandelt. Also T = Datentyp von arr (in dem Fall integer) und a ist auch immer = Datentyp von arr, weil für a der Datentyp von arr genutzt wird
    Das ist vielleicht etwas verwirrend für dich, da es sich hier um eine Extension handelt und dabei gleichzeitig auch noch eine Typparameter-Inferenz stattfindet. Man könnte das ganze auch hierzu umschreiben:

    VB.NET-Quellcode

    1. Dim a = CloneX(Of Integer())(arr)
    Das ist absolut gleichbedeutend und tatsächlich auch das, wozu der Compiler es umformt, aber die erste Variante ist halt höher abstrahiert und deswegen einfacher, wenn mans mal verstanden hat.

    RushDen schrieb:

    Ahso, dass alle drei auch Arrays sind weiß ich, dachte das wär selbstverständlich
    also in allen 3en sind Arrays drin, aber der ausgewiesene Datentyp von o ist Object, weil .Clone() halt Object returnt.
    Die datentypen der anneren sind nicht Array (doch schon, aber dassis ungenau), und auch nicht Integer, sondern Integer-Array (wie Arthentus schon sagte).
    Array ist die (MustInherit) Basis-Klasse von Integer-Array - wusstest du das?
    aber ist ebenso auch die Basis-Klasse von String-Array. Usw.

    Daher ist die Angabe, arr sei ein Array ungenügend, mit ganz praktischen Auswirkungen

    VB.NET-Quellcode

    1. dim arr As Array = {3,4,5,6}
    2. dim n2 As Integer = arr(2) 'geht nicht, weil der Compiler nicht den genauen Datentyp von arr kennt

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

    ja, dassis sprachlich schwierig, denn den Datentyp Integer-Array schreibt man in vb so: Integer().
    Weil aber die Klammern so leicht übersehen werden, rede ich lieber von Integer-Array, mit natürlich dem Nachteil, dass die Leuts weniger die korrekte Deklaration zu erkennen üben.
    deswegen sag ich arr ist ein Array.
    was ja, wie ausgeführt, unzulänglich ist. Dabei fällt mir auf, du hast meine 3 Fragen noch garnet beantwortet, nur die 2. , dass .Clone() Datentyp Object zurückgibt.
    Also nochma

    VB.NET-Quellcode

    1. Public Sub Main()
    2. Dim arr = Enumerable.Range(2, 3).ToArray
    3. Dim o = arr.Clone
    4. Dim a = arr.CloneX
    5. End Sub
    mw schrittweise:
    Welchen Datentyp gibt Enumerable.Range() zurück?