Klasse als eine Art von Datentyp

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von concu.

    Klasse als eine Art von Datentyp

    Hallo,

    ich wollte hier von irgendwelchen Strings in denen ich diverse Informationen "enkodiert" habe (so was wie "1;bla;true") wegkommen und das ganze mit einem Objekt eines eigenen Datentyps machen. Deswegen habe ich einen Branch angelegt und mal was ausprobiert. Inzwischen habe ich auch eine Lösung gefunden mit der allerdings FxCop nicht zufrieden ist. Meine Lösung sieht so aus:

    VB.NET-Quellcode

    1. Public MustInherit Class HistoryItem
    2. Private _identifier As Integer
    3. Private _title As String
    4. Public ReadOnly Property Identifier As Integer
    5. Get
    6. Return _identifier
    7. End Get
    8. End Property
    9. Public ReadOnly Property Title As String
    10. Get
    11. Return _title
    12. End Get
    13. End Property
    14. Public Overrides Function toString() As String
    15. Return _title
    16. End Function
    17. Public Class HistoryItemWindow
    18. Inherits HistoryItem
    19. Private _filmnr As Integer
    20. Public ReadOnly Property Filmnr As Integer
    21. Get
    22. Return _filmnr
    23. End Get
    24. End Property
    25. Public Sub New(title As String, identifier As Integer, filmnr As Integer)
    26. MyBase._title = title
    27. MyBase._identifier = identifier
    28. Me._filmnr = filmnr
    29. End Sub
    30. End Class
    31. Public Class HistoryItemSearchResult
    32. Inherits HistoryItem
    33. Private _searchTerm As String
    34. Private _sortOrder As SortOrder
    35. Private _sortedColumn As DataGridViewColumn
    36. Public ReadOnly Property SearchTerm As String
    37. Get
    38. Return _searchTerm
    39. End Get
    40. End Property
    41. Public ReadOnly Property SortOrder As SortOrder
    42. Get
    43. Return _sortOrder
    44. End Get
    45. End Property
    46. Public ReadOnly Property SortedColumn As DataGridViewColumn
    47. Get
    48. Return _sortedColumn
    49. End Get
    50. End Property
    51. Public Sub New(title As String, searchTerm As String, sortOrder As SortOrder, sortedColumn As DataGridViewColumn)
    52. MyBase._title = title
    53. MyBase._identifier = 2
    54. Me._searchTerm = searchTerm
    55. Me._sortOrder = sortOrder
    56. Me._sortedColumn = sortedColumn
    57. End Sub
    58. End Class
    59. End Class


    Und dies nutze ich in folgenden Formen:

    VB.NET-Quellcode

    1. Dim objHistoryItemSearchResult As HistoryItem.HistoryItemSearchResult = DirectCast(e, HistoryItem.HistoryItemSearchResult)
    2. GlobalNeededFunctions.SearchInDatabaseCmplExp(objHistoryItemSearchResult.SearchTerm)
    3. TabSearch.RestoreSorting(objHistoryItemSearchResult)[/code]
    4. [code]Public Shared Sub RestoreSorting(e As HistoryItem.HistoryItemSearchResult)
    5. ...
    6. newColumn = dgv.Columns(e.SortedColumn.Name)
    7. ...



    VB.NET-Quellcode

    1. History.OpenEntry(DirectCast(LstHistory.SelectedItem, HistoryItem))

    VB.NET-Quellcode

    1. Public Sub OpenEntry(e As HistoryItem)
    2. ...
    3. Dim id As Integer = e.Identifier
    4. ...
    5. Select Case id
    6. Case 0
    7. ' MovieDetail-Window
    8. OpenMovieDetails(DirectCast(e, HistoryItem.HistoryItemWindow))
    9. Case 1
    10. ' MovieEdit-Window
    11. OpenEditMovie(DirectCast(e, HistoryItem.HistoryItemWindow))
    12. Case 2
    13. ' SearchTab
    14. ...
    15. End Select
    16. ...
    17. End Sub



    VB.NET-Quellcode

    1. Private Sub FrmMovieDetails_Closing() Handles MyBase.FormClosing
    2. Dim itemWindow As New HistoryItem.HistoryItemWindow(LblTitle.Text & " (Detailfenster)", 0, _filmnr)
    3. ...
    4. FrmHistory.LstHistory.Items.Insert(0, itemWindow)
    5. ...
    6. End Sub


    Ich habe also eine übergeordnete Klasse "HistoryItem" mit zwei Attributen, welche die beiden Klassen "HistoryItemWindow" und "HistoryItemSearchResult" gemeinsam haben. Die beiden Klassen haben aber natürlich auch Attribute, die sich speziell auf sie beziehen. Ich brauche z.B. keinen "SearchTerm" bei einem "HistoryItemWindow". "HistoryItemWindow" und "HistoryItemSearchResult" haben beide Konstruktoren, damit ich ein Objekt diesen Typs darüber instanziieren kann.

    Jedenfalls habe ich mit dieser Lösung wohl gegen den guten Geschmack verstoßen. FxCop meint:
    CA1034 Geschachtelte Typen sollten nicht sichtbar sein Schachteln Sie den Typ 'HistoryItem.HistoryItemWindow' nicht. Ändern Sie stattdessen seinen Zugriff so, dass er nicht extern sichtbar ist. MDb HistoryItem.vb 21


    Wie kriege ich das sauber hin?

    Grüße
    concu

    Edit by ~blaze~:
    *Codetag zu VB.Net geändert*

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

    Ja, die Meldung vom FxCop habe ich wohl verstanden. Ich habe nur keine Ahnung wie ich das anders aufbauen kann bei gleichbleibender Funktion.

    Ich habe heute morgen noch erfolglos folgendes ausprobiert (ich hoffe, dass ist noch die Variante, wie ich sie jetzt im Kopf habe):

    VB.NET-Quellcode

    1. Public MustInherit Class Class1
    2. Private _class1A As Boolean
    3. Public class2 As class2
    4. Public class3 As class3
    5. Public ReadOnly Property class1A As Boolean
    6. Get
    7. Return _class1A
    8. End Get
    9. End Property
    10. End Class
    11. Public Class class2
    12. Inherits Class1
    13. Private _class2A As Boolean
    14. Public Sub New(a As Boolean)
    15. MyBase._class1A = Not a
    16. Me._class2A = a
    17. End Sub
    18. Public ReadOnly Property class2A As Boolean
    19. Get
    20. Return _class2A
    21. End Get
    22. End Property
    23. End Class
    24. Public Class class3
    25. Inherits Class1
    26. Private _class3A As Boolean
    27. Public Sub New(a As Boolean)
    28. Me._class3A = a
    29. End Sub
    30. Public ReadOnly Property class3A As Boolean
    31. Get
    32. Return _class3A
    33. End Get
    34. End Property
    35. End Class


    Kompiliert nicht wegen der Zeile 18 mit dem "MyBase._class1A = Not a", weil ich dann natürlich nicht auf "class1A" in "class1" zugreifen kann. Wenn es geschachtelt ist wie oben, dann geht das.
    Zudem kam dies:

    VB.NET-Quellcode

    1. Dim test As New class2(True)
    2. Debug.WriteLine(test.class3.class3A)

    Hier kann ich von der Instanz "test" von "class2" auf "class3" zugreifen. Soll meiner Meinung nach auch nicht gehen.

    Edit by ~blaze~:
    *Codetag zu VB.Net geändert*

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

    Also was du da machst ergibt für mich keinen Sinn, deswegen versuch ich auch nicht, da was zu korrigieren.
    Der korrekte Code für oben wäre allerdings:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. ​Public MustInherit Class HistoryItem
    2. Protected _identifier As Integer
    3. Protected _title As String
    4. Public ReadOnly Property Identifier As Integer
    5. Get
    6. Return _identifier
    7. End Get
    8. End Property
    9. Public ReadOnly Property Title As String
    10. Get
    11. Return _title
    12. End Get
    13. End Property
    14. Public Overrides Function toString() As String
    15. Return _title
    16. End Function
    17. End Class
    18. Public Class HistoryItemWindow : Inherits HistoryItem
    19. Private _filmnr As Integer
    20. Public ReadOnly Property Filmnr As Integer
    21. Get
    22. Return _filmnr
    23. End Get
    24. End Property
    25. Public Sub New(title As String, identifier As Integer, filmnr As Integer)
    26. _title = title
    27. _identifier = identifier
    28. _filmnr = filmnr
    29. End Sub
    30. End Class
    31. Public Class HistoryItemSearchResult : Inherits HistoryItem
    32. Private _searchTerm As String
    33. Private _sortOrder As SortOrder
    34. Private _sortedColumn As DataGridViewColumn
    35. Public ReadOnly Property SearchTerm As String
    36. Get
    37. Return _searchTerm
    38. End Get
    39. End Property
    40. Public ReadOnly Property SortOrder As SortOrder
    41. Get
    42. Return _sortOrder
    43. End Get
    44. End Property
    45. Public ReadOnly Property SortedColumn As DataGridViewColumn
    46. Get
    47. Return _sortedColumn
    48. End Get
    49. End Property
    50. Public Sub New(title As String, searchTerm As String, sortOrder As SortOrder, sortedColumn As DataGridViewColumn)
    51. _title = title
    52. _identifier = 2
    53. _searchTerm = searchTerm
    54. _sortOrder = sortOrder
    55. _sortedColumn = sortedColumn
    56. End Sub
    57. End Class
    Danke. Sieht aus als wäre das die Lösung. Ich hatte "Protected" überhaupt nicht auf dem Schirm, mit "Private" ging es nicht und "Public" wollte ich die beiden Attribute nicht machen.

    Du meintest, dass der zweite Versuch überhaupt keinen Sinn gemacht hat oder generell?

    concu schrieb:

    VB.NET-Quellcode

    1. Public class2 As class2
    Solche Namensgebungen dürften dem FxCop auch nicht gefallen.
    1. der Name der Klasse class2,
    2. der Name der Instanz class2 vom Typ class2.
    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!

    concu schrieb:

    schneller Test
    Auch das ist suboptimal, denn wenn es mehr als nur ein schneller Test wird, bleiben solche Namen kleben. Wann nimmst Du Dir die Zeit, Deinen Code aufzuräumen? Richtig.
    Also vergib gleich ordentliche Namen. Da entwickelt es sich auch viel angenehmer mit.
    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!
    Das war sogar ein neues Projekt in Visual Studio, damit ich das in abgespeckter Form testen kann und ohne den ganzen "Overhead" mit den Aufrufen anpassen.
    Aber klar, ich stimme dir zu, dass man so etwas nicht in seinem richtigen Projekt machen sollte mit dem Risiko das die Bezeichner am Ende so bleiben.