Interface(Of T) als Liste führen

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    Interface(Of T) als Liste führen

    yo Leute,

    Ich habe mir ein Interface erstellt

    VB.NET-Quellcode

    1. Public Interface ICommandEntry(Of T)
    2. Sub Undo()
    3. Sub Restore()
    4. Property ValueBefore() As T
    5. Property ValueAfter() As T
    6. End Interface


    Hintergrund ist eine einfache Rückgängig <-> Wiederholen Funktion. Da es ja verschiedene Steuerelemente ansprechen soll ist der Wert ja unterschiedlich (Checkbox Boolean, Textbox String, etc.). Deswegen das T, da man dies ja in der Klasse angeben muss.
    Bsp.:

    VB.NET-Quellcode

    1. Public Class TextboxEntry
    2. Implements ICommandEntry(Of String) ' Da die .Text Eigenschaft ja String ist
    3. ....
    4. End Class


    Wie kann ich aber eine unabhängige Liste (List Of) führen ohne den Typ angeben zu müssen.

    VB.NET-Quellcode

    1. Private _lstHistory As New List(Of ICommandEntry(Of String)) ' Geht, will ich aber nicht da der Typ ja unterschiedlich sein soll
    2. Private _lstHistory As New List(Of ICommandEntry) ' Geht nicht will ich aber gerne


    Per

    VB.NET-Quellcode

    1. _lstHistory.Add(New TextboxEntry)

    will ich das dann der Liste hinzufügen können.

    Hoffe ihr versteht was ich meine :)

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Gar nicht. Außerdem wäre für sowas eher ein Stack passender als eine List. Zur Lösung kannst du höchstens ein Interface verwenden welches anstatt T ein object verwendet.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    @thefiloe: Stack löscht ja das Element welches per Pop verwendet wird oder? ich benötige das aber für die Wiederholen Methode noch.
    Das mit Typ Object woll ich eigentlich vermeiden :S
    Wenn es aber keine andere Möglichkeit gibt bleibt mir leider nichts anderes über.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Die Stack-Klasse hat auch eine Peek-Funktion, welches das oberste Element zurückgibt, ohne es zu entfernen.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    @fichz:: Oder mach da 2 Interfaces draus, lass Deine Klasse TextboxEntry beide implementieren und mach eine List(Of ICommand).

    VB.NET-Quellcode

    1. Public Interface ICommand
    2. Sub Undo()
    3. Sub Restore()
    4. End Interface
    5. Public Interface ICommandEntry(Of T)
    6. Property ValueBefore() As T
    7. Property ValueAfter() As T
    8. End Interface
    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!
    Ich habe jetzt eine Mixtur aus beiden gemacht und es schreibt zumindest keine Fehler mehr her. Werde nun testen ob es so funktionieren kann :)

    VB.NET-Quellcode

    1. Public Interface ICommandEntry(Of T)
    2. Inherits ICommandEntry
    3. Property ValueBefore() As T
    4. Property ValueAfter() As T
    5. End Interface
    6. Public Interface ICommandEntry
    7. Sub Undo()
    8. Sub Restore()
    9. End Interface


    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Ich würds eigentlich eher so lösen:

    VB.NET-Quellcode

    1. Public Interface Iabc
    2. Sub A()
    3. Sub B()
    4. Property C() As Object
    5. Property D() As Object
    6. End Interface
    7. Public Interface Iabc(Of T)
    8. Inherits Iabc
    9. Overloads Property C As T
    10. Overloads Property D As T
    11. End Interface

    So ist nämlich das Interface Iabc nicht speziell typisiert, das Interface Iabc(Of T) allerdings schon (du könntest dir das Interface Iabc auch als Iabc(Of Object) vorstellen, ist ja im Grunde genommen das selbe) :).

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

    Hi
    wie wäre es mit folgender Stuktur?

    VB.NET-Quellcode

    1. Public MustInherit Class HistoryEntry
    2. Public MustOverride ReadOnly Property DisplayName As String
    3. public MustOverride ReadOnly Property Description As String
    4. Public MustOverride Sub Undo()
    5. Public MustOverride Sub Do()
    6. Public Overridable Sub Redo()
    7. Do()
    8. End Sub
    9. End Class
    10. Public Class History
    11. Private _entries As New LinkedList(Of HistoryEntry)
    12. Private _trailingEntry As LinkedListNode(Of HistoryEntry)
    13. Public Sub Do(action As HistoryEntry)
    14. Dim cen As LinkedListNode(Of HistoryEntry) = _trailingEntry
    15. Dim pen As LinkedListNode(Of HistoryEntry)
    16. While cen IsNot Nothing
    17. pen = cen
    18. cen = cen.Next
    19. _entries.Remove(pen)
    20. End While
    21. _trailingEntry = Nothing
    22. _entries.AddLast(action)
    23. action.Do()
    24. End Sub
    25. Public Sub Undo()
    26. _trailingEntry = If(_trailingEntry Is Nothing, _entries.Last, _trailingEntry.Previous)
    27. If _trailingEntry Is Nothing Then Throw New InvalidOperationException("No actions to undo available.")
    28. _trailingEntry.Undo()
    29. End Sub
    30. Public Sub Redo()
    31. If _trailingEntry Is Nothing Then Throw New InvalidOperationException("No undone actions available.")
    32. _trailingEntry.Redo()
    33. _trailingEntry = _trailingEntry.Next
    34. End Sub
    35. Public ReadOnly Property CanUndo As Boolean
    36. Get
    37. Return If(_trailingEntry Is Nothing, _entries.Last, _trailingEntry.Previous) IsNot Nothing
    38. End Get
    39. End Property
    40. Public ReadOnly Property CanRedo As Boolean
    41. Get
    42. Return _trailingEntry IsNot Nothing
    43. End Get
    44. End Property
    45. End Class

    oder irgendwie so.

    Gruß
    ~blaze~
    um nochma an post#1 anzuknüpfen:

    VB.NET-Quellcode

    1. Public Interface ICommandEntry(Of T)
    2. Sub Undo()
    3. Sub Restore()
    4. Property ValueBefore() As T
    5. Property ValueAfter() As T
    6. End Interface
    7. Public Class CommandEntryList(Of T) : Inherits List(Of ICommandEntry(Of T))
    8. End Class


    Ansonsten ist der Command-Pattern mit Undo ein Mords-Aufwand - also nur ein Ansatz ist abgehandelt in Undo-ReDo-List

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

    Hey,
    mir ist da doch noch ne Möglichkeit eingefallen wie du Unterschiedliche Typen in einer List<> unterbringen kannst, die ich so aus C++ kenne. Nennt sich Type erasure.
    Beispiel

    C-Quellcode

    1. public interface ICommandEntry<T>
    2. {
    3. void Undo();
    4. void Restore();
    5. T ValueBefore { get; set; }
    6. T ValueAfter { get; set; }
    7. }
    8. public interface IMainStorage
    9. { };
    10. public class CommandWrapp<T> : IMainStorage
    11. {
    12. public CommandWrapp(ICommandEntry<T> val) { rawdata = val; }
    13. private ICommandEntry<T> rawdata;
    14. public ICommandEntry<T> RawData { get {return rawdata;}}
    15. };
    16. public class CommandEntry
    17. {
    18. public void SetData<T>(ICommandEntry<T> val)
    19. {
    20. data = new CommandWrapp<T>(val);
    21. }
    22. public ICommandEntry<T> Getdata<T>()
    23. {
    24. return ((CommandWrapp<T>)(data)).RawData;
    25. }
    26. private IMainStorage data;
    27. };
    28. class test : ICommandEntry<int>
    29. {
    30. public test(int i) { fi = i; }
    31. int fi;
    32. public void Undo()
    33. {
    34. MessageBox.Show("Hallo: " + fi);
    35. }
    36. // und die anderen Implementierungen..
    37. };
    38. private void test()
    39. {
    40. test i = new test(7);
    41. List<CommandEntry> list = new List<CommandEntry>();
    42. CommandEntry entry = new CommandEntry();
    43. entry.SetData<int>(i);
    44. list.Add(entry);
    45. list[0].Getdata<int>().Undo();
    46. }

    Das Ganze beruht eigentlich nur auf Polymorphie und Templates. Da Templates aber so sparsam implementiert wurden in C#, ists in der Anwendung komplizierter. In C++ könnt man hier eben SetData als Konstruktor setzen oder =-Operator überladen. Du könntest auch im Interface IMainStorage die Methoden UnDo() und Restore() implementieren, da müsste man den Typen nicht kennen.

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