Wie zugreifen auf unterschiedliche Datentypen in einer Liste?

  • VB.NET

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von FAtheone.

    Wie zugreifen auf unterschiedliche Datentypen in einer Liste?

    Hallo, ich habe vor eine Liste anzulegen, die zwei unterschiedliche Datentypen enthält, die aber von einem gemeinsamen Datentypen abgeleitet wurden. 8|

    Datentyp "matrix" und "scalar" wurden jeweils vom Datentyp "operand" abgeleitet. Mein Ziel ist es Objekte vom Datentyp "matrix" und "scalar" in einer Liste zu speichern und später darauf zuzugreifen.

    Zum Beispiel so:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public Function Rechnung(ByVal Test As List(Of class_matrix.operand)) As Double
    3. For Each Element In Test
    4. If TypeOf Element Is class_matrix.matrix Then
    5. 'folgede Eigenschaft steht nur im Datentyp matrix zur Verfügung
    6. Element.num_spalten = 8 '<-- hier tritt ein Fehler auf: ...ist kein Member von "class_matrix.operand"
    7. End If
    8. If TypeOf Element Is class_matrix.scalar Then
    9. 'folgede Eigenschaft steht nur im Datentyp scalar zur Verfügung
    10. Element.value = 99.6 '<-- hier tritt ein Fehler auf: ...ist kein Member von "class_matrix.operand"
    11. End If
    12. Next
    13. End Function
    14. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    15. 'Liste die Elemente des Datentyps operand enthält
    16. Dim meine_Liste As New List(Of class_matrix.operand)
    17. 'Die Datentypen matrix und scalar sind vom Datentyp operand abgeleitet
    18. Dim _matrix As New class_matrix.matrix
    19. Dim _scalar As New class_matrix.scalar
    20. meine_Liste.Add(_matrix)
    21. meine_Liste.Add(_scalar)
    22. Rechnung(meine_Liste)
    23. End Sub
    24. End Class


    Wie kann ich also zum Ausdruck bringen, dass eine bestimmte Aktion nur ausgeführt wird, wenn der Datentyp der richtige ist?
    Habe etwas von IEnumerable(Of T) anstatt List(of T)gelesen.

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

    VB.NET-Quellcode

    1. f TypeOf bla Is Matrix Then

    kann man auch außerhalb verwenden.

    VB.NET-Quellcode

    1. DIrectCast(var, type)


    An Sonsten brauchst du wohl eher ein Interface

    BTW:
    Namenskonvention von Klassen: Großbuchstabe; mehrere Worteteile hintereinander duch Großbuchstaben abgetrennt; kein Pre-/ Suffix: Matrix; Scalar
    Namenskonvention von Interfaces: siehe Klassen; Prefix "I" -> IOperand

    VB.NET-Quellcode

    1. Public Class Matrix Implements IOperand
    2. Public Class Scalar Implements IOperand
    3. Public Interface IOperand
    4. Property Element(index As Integer) As Double 'Public ist nicht erforderlich und nicht erlaubt.
    5. End Interface
    Es ist auch möglich, die Liste in Rechnung() vorher zu filtern, dann passen die Typen automatisch:

    VB.NET-Quellcode

    1. Dim part1 As IEnumerable(Of class_matrix.matrix) = From m In Test Where TypeOf m Is class_matrix.matrix Select DirectCast(m, class_matrix.matrix)
    2. For Each element As class_matrix.matrix In part1
    3. 'DoSomething
    4. Next

    Der Vorschlag mit dem Interface ist gut (und auch vorzuziehen), allerdings ist der Bezeichner der Eigenschaft dann bei beiden Varianten gleich. Sollen die Namen unterschiedlich sein (.Value und .Num_Spalten), hilft das Interface auch nicht unbedingt weiter. Vielleicht sollte da noch ein wenig am Design des Codes gedreht werden. Warum haben z.B. Matrix und Skalar denselben Basistyp? Solche Beziehungen funktionieren nur, wenn die Typen auch zueinander passen, etwa "Zahl" als Basisklasse von "ReelleZahl" und "GanzeZahl".
    Gruß
    hal2000
    Als Interface könnte z.B.
    IOperand

    die ganzen Rechenreglen beinhalten (.Add etc.), sowie einen "Wert" (Vektor-Betrag, Matrix-Determinante, Skalar-Wert) o.ä.
    Je nach durchgeführten Operationen.

    Wenn mit Basisklassen, dann könnte man Vektor z.B. von Matrix ableiten (als 1xn-Matrix bzw. nx1-Matrix)