Benutzer mit den meisten Antworten
Typübernahme von Me in der Basisklasse

Frage
-
Hallo,
ich habe einen Serialisier zum 1:1 Kopieren beliebiger Objekte. In der Basisklasse möchte ich eine Funktion implementieren, die mir definiert Eigenschaften der Kopie ändert. Wie muss die Syntax bei "As Object" jeweils lauten, damit ich dort den gleichen Typ wie "Me" bekomme? Me.GetType gibt es nicht.Public Function GetKopieSpezial() As Object Dim merke As Object = Serialiser.GetKopie(Me) With DirectCast(merke, IBasis) .Guid = System.Guid.NewGuid.ToString("N").ToLower .Name = .PraefixName + .Guid .GuidVorlage = DirectCast(Me, IBasis).Guid End With Return merke End Function
Peter
Antworten
-
Hallo Peter,
das könnte so funktionieren.Module Module1
Public Sub Main()
Dim objA As New KlasseA
Dim objB As New KlasseB
' objA.GetKopie hat einen Rückgabewert vom Typ KlasseA.
Dim objA1 = objA.GetKopie
' objB.GetKopie hat einen Rückgabewert vom Typ KlasseB.
Dim objB1 = objB.GetKopie
End Sub
<Serializable()> Public MustInherit Class BasisKlasse
Public Guid As String
Public GuidVorlage As String
End Class
<Serializable()> Public MustInherit Class BasisKlasse_Derived(Of clsDerivedClass_TP As BasisKlasse)
Inherits BasisKlasse
Public Function GetKopie() As clsDerivedClass_TP
Dim kopie As BasisKlasse = GetDuplikat(Me)
kopie.GuidVorlage = Me.Guid
Return DirectCast(kopie, clsDerivedClass_TP)
End Function
End Class
<Serializable()> Public Class KlasseA
Inherits BasisKlasse_Derived(Of KlasseA)
End Class
<Serializable()> Public Class KlasseB
Inherits BasisKlasse_Derived(Of KlasseB)
End Class
Public Function GetDuplikat(Of T)(ByVal obj As T) As T
Dim memoStream = New System.IO.MemoryStream
Dim binFormatter = New Runtime.Serialization.Formatters.Binary.BinaryFormatter
binFormatter.Serialize(memoStream, obj)
memoStream.Position = 0
Return CType(binFormatter.Deserialize(memoStream), T)
End Function
End Module
- Bearbeitet Markus222 Donnerstag, 5. Juli 2012 19:57
- Als Antwort vorgeschlagen Heslacher Freitag, 6. Juli 2012 06:16
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 26. Juli 2012 11:39
Alle Antworten
-
Hallo Peter,
wenn ich Dich richtig verstanden habe ( was ich einfach mal bezweifle ;-) ) sollte As Object einfach As NameDeinerKlasse sein.
z.B.
Public Class Test Public Function GetKopieSpezial() as Test Dim merke As Test .... Return merke End Function End Class '
Hannes
If you have got questions about this, just ask.
In a perfect world,
users would never enter data in the wrong form,
files they choose to open would always exist
and code would never have bugs.
C# to VB.NET: http://www.developerfusion.com/tools/convert/csharp-to-vb/ -
ich der Tat war mein Anliegen nicht richtig verstanden. Mit nachfolgendem Code funktioniert das ganze, aber ich hätte gerne den GetKopie-Return irgendwie generisch im selben Typ wie die zu kopierende Klasse.
Public Sub Main() Dim objA As New KlasseA Dim objB As New KlasseB Dim objA2 = objA.GetKopie Dim objB2 = objB.GetKopie End Sub <Serializable()> Public MustInherit Class BasisKlasse Public Guid As String Public GuidVorlage As String Public Function GetKopie() As Object Dim kopie = GetDuplikat(Me) kopie.GuidVorlage = Me.Guid Return kopie End Function End Class <Serializable()> Public Class KlasseA Inherits BasisKlasse End Class <Serializable()> Public Class KlasseB Inherits BasisKlasse End Class Public Shared Function GetDuplikat(Of T)(ByVal obj As T) As T Dim memoStream = New System.IO.MemoryStream Dim binFormatter = New Runtime.Serialization.Formatters.Binary.BinaryFormatter binFormatter.Serialize(memoStream, obj) memoStream.Position = 0 Return CType(binFormatter.Deserialize(memoStream), T) End Function
mit folgenden überladenen Methoden ginge es auch, aber generisch in einer Funktion ist halt eleganter
... Dim objA2 As KlasseA = BasisKlasse.GetKopie(objA) ... Public Shared Function GetKopie(ByVal obj As KlasseA) As KlasseA Dim kopie = GetDuplikat(obj) kopie.GuidVorlage = obj.Guid Return kopie End Function Public Shared Function GetKopie(ByVal obj As KlasseB) As KlasseB Dim kopie = GetDuplikat(obj) kopie.GuidVorlage = obj.Guid Return kopie End Function
Peter
-
Hallo Peter,
das könnte so funktionieren.Module Module1
Public Sub Main()
Dim objA As New KlasseA
Dim objB As New KlasseB
' objA.GetKopie hat einen Rückgabewert vom Typ KlasseA.
Dim objA1 = objA.GetKopie
' objB.GetKopie hat einen Rückgabewert vom Typ KlasseB.
Dim objB1 = objB.GetKopie
End Sub
<Serializable()> Public MustInherit Class BasisKlasse
Public Guid As String
Public GuidVorlage As String
End Class
<Serializable()> Public MustInherit Class BasisKlasse_Derived(Of clsDerivedClass_TP As BasisKlasse)
Inherits BasisKlasse
Public Function GetKopie() As clsDerivedClass_TP
Dim kopie As BasisKlasse = GetDuplikat(Me)
kopie.GuidVorlage = Me.Guid
Return DirectCast(kopie, clsDerivedClass_TP)
End Function
End Class
<Serializable()> Public Class KlasseA
Inherits BasisKlasse_Derived(Of KlasseA)
End Class
<Serializable()> Public Class KlasseB
Inherits BasisKlasse_Derived(Of KlasseB)
End Class
Public Function GetDuplikat(Of T)(ByVal obj As T) As T
Dim memoStream = New System.IO.MemoryStream
Dim binFormatter = New Runtime.Serialization.Formatters.Binary.BinaryFormatter
binFormatter.Serialize(memoStream, obj)
memoStream.Position = 0
Return CType(binFormatter.Deserialize(memoStream), T)
End Function
End Module
- Bearbeitet Markus222 Donnerstag, 5. Juli 2012 19:57
- Als Antwort vorgeschlagen Heslacher Freitag, 6. Juli 2012 06:16
- Als Antwort markiert Robert BreitenhoferModerator Donnerstag, 26. Juli 2012 11:39
-
Hallo Markus,
leider funktioniert das nicht
...Dim kopie As BasisKlasse = GetDuplikat(Me) ...: Hier kommt die Fehlermeldung "Der Verweis auf einen nicht freigegebenen Member erfordert einen Objektverweis".
Ich vermute, dass es auch ohnehin nicht funktionieren würde, da "Dim kopie As BasisKlasse" das Objekt ja nur als Basisklasse definieren würde. Die KlasseA, KlasseB .. werden ja noch um etliche Member erweitert, die dann fehlen würden.
Ich vermute der elegante Lösungsansatz ist irgendwie Generisch gelagert (ähnlich "Function GetDuplikat"), aber irgendwie hab ich hier noch nicht die Lösung gefunden. Ich hab im Moment mit der Überladung das Kopieren funktionsfähig implementiert, es ist für mich trotzdem eine kleine Herausforderung eine generische Lösung zu finden (falls möglich).
Gruß Peter
Peter
-
Dieser Ansatz ist generisch. Er gibt KlasseA und KlasseB als Typparameter an die Basisklasse.
In Sub Main könnte objA1 auch direkt als KlasseA deklariert werden. Das wäre auch klarerer Code.
Public Sub Main()
Dim objA As New KlasseA
Dim objB As New KlasseB
' objA.GetKopie in der gemeinsamen BasisKlasse_Derived hat hier einen Rückgabewert vom Typ
' KlasseA.
' Dim objB1 As KlasseB = objA.GetKopie würde eine Fehlermeldung erzeugen.
' Value of type 'WindowsApplication1.Module1.KlasseA' cannot be converted to
' WindowsApplication1.Module1.KlasseB'.
Dim objA1 As KlasseA = objA.GetKopie
' objB.GetKopie in der gemeinsamen BasisKlasse_Derived hat hier einen Rückgabewert vom Typ
' KlasseB.
Dim objB1 As KlasseB = objB.GetKopie
End Sub
Me in GetKopie verweist auf eine KlasseA oder KlasseB Instanz (also Klasseninstnz = Objekt). GetKopie gibt ein KlasseA oder KlasseB Objekt zurück. kopie es ist zwar mit Basisklasse definiert. Ist aber im Fall oben ein Zeiger auf das kopierte neue KlasseA oder KlasseB Objekt. Sonst ginge der DirectCast nicht in der Return Anweisung.
Du kannst dort einen Breakpoint setzen und im Debug wird dir der Klassenname angezeigt wenn du mit der Maus auf Me zeigst.
MyClass würde auf die Baisisklasse Intanz verweisen.
Ich habe oben in KlasseA bei mir dann noch ein Private Test As String = "Test1".
Diese Variable war dann so auch in der Kopie ObjA1 vorhanden.Bei mir erscheint keine Fehlermeldung. Option explicit habe ich auf On. Option Strict On. Option
infer On.Du könntest das Beispiel ja mal exakt so in ein Modul kopieren und schauen ob es dann funktioniert.
Würde dir auch vorschlagen das Beispiel dann schrittweise zu debuggen und mit der Maus in jeder Zeile auf die Variablennamen zu zeigen so dass du ihren Datentyp siehst. Oder du lässt dir das Locals Windows anzeigen. Das ist komfortabler.Vermute das der Ort von GetDuplikat der Grund für die Fehlermeldung ist. Du könntest diese Funktion in eine separate Klasse ausgliedern und Shared deklarieren. Z.B. clsCopyFunctions. Der Aufruf wäre dann direkt über die Klasse clsCopyFunctions.GetKopie. D.h. ein CopyFunctions Objekt ist nicht nötig.
- Bearbeitet Markus222 Freitag, 6. Juli 2012 17:16
-
Die methode GetDuplikat() muss in die BasisKlasse_derived und kann dort dann auch noch als private rein. Es funktioniert, wie in der Sub Main von Markus beschrieben.
Hannes
If you have got questions about this, just ask.
In a perfect world,
users would never enter data in the wrong form,
files they choose to open would always exist
and code would never have bugs.
C# to VB.NET: http://www.developerfusion.com/tools/convert/csharp-to-vb/