Benutzer mit den meisten Antworten
Generische MustInherit Klasse

Frage
-
Hallo zusammen,
bisher hatte ich 2 MustInherit Klassen :
'Visual Basic 2008 - .net 3.5 - Any CPU Public MustInherit Class BaseObject End Class Public MustInherit Class BaseObjectList(Of T As {New, BaseObject}) Inherits List(Of T) End Class
nun möchte ich noch eine generische MustInherit Klasse erstellen, die wiederum von List(Of T) erbt, mit der Einschränkung dass T vom Typ BasObjectList ist und auch von dieser Klasse erstellt werden kann mittels as New T().
'Visual Basic 2008 - .net 3.5 - Any CPU Public MustInherit Class ListOfBaseObjectList(Of T As {new,BaseObjectList}) Inherits List(Of T) End Class
Schreibe ich dies so, erhalte ich "Nicht genügend Typargumente für BaseObjectList(Of T)".Schreibe ich es so:
'Visual Basic 2008 - .net 3.5 - Any CPU Public MustInherit Class ListOfBaseObjectList(Of T As {new,BaseObjectList(Of BaseObject)}) Inherits List(Of T) End Class
erhalte ich "Das Typargument BaseObject wurde als MustInherit deklariert und erfüllt nicht die Anforderungen der New-Einschränkung für den T-Typparameter."
Geht das überhaupt und wenn ja, wie ist die korrekte Schreibweise ?
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/
Antworten
-
Hallo Hannes,
das wird nicht funktionieren. Zulässig sind nur implizite Konvertierungen
Und die sind (bei .NET 4.0) auf Schnittstellen (und Delegaten) beschränkt - bei .NET 3.5 / VB 2008 hört es noch früher auf.
Siehe Eric Lippert: Covariance and Contravariance FAQDie Fehlermeldung resultiert daraus, dass BaseObjectList ein offener Typ ist,
d. h. hier muss T angegeben werden:Public MustInherit Class ListOfBaseObjectList(Of T As {BaseObjectList(Of T), New})
Inherits BaseObjectList(Of T)
End Classwomit Du aber nur beim nächsten Fehler landest:
Type argument 'T' does not inherit from or implement the constraint type 'BaseObject'.Und Deine Variante (BaseObject funktioniert nicht, da eine abstrakte Klasse nie für sich existieren kann.
Ersetzt man das durch ein Interface, würde man zwar den Code kompilieren können,
aber dann ist bei der konkreten Implementation Schluss:Public Interface IBaseObject End Interface Public MustInherit Class BaseObject Implements IBaseObject End Class Public MustInherit Class BaseObjectList(Of T As {IBaseObject, New}) Inherits List(Of T) End Class Public MustInherit Class ListOfBaseObjectList(Of T As {IList(Of IBaseObject), New}) Inherits List(Of T) End Class Public Class ConcreteObject Inherits BaseObject End Class Public Class ConcreteList Inherits BaseObjectList(Of ConcreteObject) End Class <br/>' Funktioniert nicht... Public Class ConcreteListList Inherits ListOfBaseObjectList(Of ConcreteList) End Class
Summa Summarum: Wozu soll das Ganze dienen?Gruß Elmar
- Als Antwort markiert Heslacher Mittwoch, 24. August 2011 09:02
-
Hallo Hannes,
ich kann nur betonen, es funktioniert nicht.
Es ist erforderlich, dass eine implizite Konvertierung existiert, und dies gilt für eine List(Of Irgendwas) nicht.
Was auch besser ist, sonst könntest Du z. B. aus einem Vogel einen Affen machen,
wenn Du Dir für BaseObject einsetzt "Tier" und die konkrete Klasse "Vogel", "Affe" wären.
Nur dem Affen das Fliegen beizubringen ist damit nicht möglich ;-)Meine Frage gestern zielte mehr darauf ab, was Du mit der Liste einer Liste lösen möchtest.
Denn für Business Objekte sehe ich direkt keine Notwendigkeit, z. B. Kunden und Aufträge zusammen zufassen.Helfen könnte man sich mit Dingen wie MakeGenericType.
Nicht erreichen kann damit aber, dass bereits zur Kompilierzeit typsichere Klassen existieren,
denn dem steht obiges entgegen.
Das fällt in etwa in die Kategorie, wie es Simulated Covariance for .NET Generics beschreibt.Gruß Elmar
- Als Antwort markiert Heslacher Mittwoch, 24. August 2011 09:02
Alle Antworten
-
Hallo Hannes,
das wird nicht funktionieren. Zulässig sind nur implizite Konvertierungen
Und die sind (bei .NET 4.0) auf Schnittstellen (und Delegaten) beschränkt - bei .NET 3.5 / VB 2008 hört es noch früher auf.
Siehe Eric Lippert: Covariance and Contravariance FAQDie Fehlermeldung resultiert daraus, dass BaseObjectList ein offener Typ ist,
d. h. hier muss T angegeben werden:Public MustInherit Class ListOfBaseObjectList(Of T As {BaseObjectList(Of T), New})
Inherits BaseObjectList(Of T)
End Classwomit Du aber nur beim nächsten Fehler landest:
Type argument 'T' does not inherit from or implement the constraint type 'BaseObject'.Und Deine Variante (BaseObject funktioniert nicht, da eine abstrakte Klasse nie für sich existieren kann.
Ersetzt man das durch ein Interface, würde man zwar den Code kompilieren können,
aber dann ist bei der konkreten Implementation Schluss:Public Interface IBaseObject End Interface Public MustInherit Class BaseObject Implements IBaseObject End Class Public MustInherit Class BaseObjectList(Of T As {IBaseObject, New}) Inherits List(Of T) End Class Public MustInherit Class ListOfBaseObjectList(Of T As {IList(Of IBaseObject), New}) Inherits List(Of T) End Class Public Class ConcreteObject Inherits BaseObject End Class Public Class ConcreteList Inherits BaseObjectList(Of ConcreteObject) End Class <br/>' Funktioniert nicht... Public Class ConcreteListList Inherits ListOfBaseObjectList(Of ConcreteList) End Class
Summa Summarum: Wozu soll das Ganze dienen?Gruß Elmar
- Als Antwort markiert Heslacher Mittwoch, 24. August 2011 09:02
-
Hallo Elmar,
erstmal vielen Dank für die Antwort.
Ich habe natürlich auch die konkreten Klassen for BaseObject bzw. BaseObjectList. Diese konkreten Klassen stellen meine Buisness Objekte dar.
Als kleines Beispiel nocheinmal ausführlicher:
'Visual Basic 2008 - .net 3.5 - Any CPU ' Das funktioniert Public MustInherit Class BaseObject Public Sub New() End Sub End Class Public MustInherit Class BaseObjectList(Of T As {New, BaseObject}) Inherits List(Of T) Public Sub AddNewBaseObject() Dim newBaseObject As New T Me.Add(newBaseObject) End Sub End Class ' Das funktioniert ebenso ' Die konkreten Klassen der mustinherit Klassen Public Class BaseTest Inherits BaseObject End Class Public Class BaseTestList Inherits BaseObjectList(Of BaseTest) End Class ' Das funktioniert leider nicht Public MustInherit Class ListOfBaseObjectList(Of T As {New, BaseObjectList(Of BaseObject)}) Inherits List(Of T) Public Sub AddNewBaseObjectList() Dim newBaseObjectList As New T Me.Add(newBaseObjectList) End Sub End Class ' Die konkrete Klasse selbstverständlich auch nicht Public Class BaseTestListList Inherits ListOfBaseObjectList(Of BaseTestList) End Class
natürlich ist das nicht die wirkliche implementierung.Mein Ziel ist es die Klasse BaseTestListList zu erstellen, die ,da sie von List(Of T) erbt, Listen von BaseTestList verwaltet, die wiederum elemente von BaseTest enthält.
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/ -
Hallo Hannes,
ich kann nur betonen, es funktioniert nicht.
Es ist erforderlich, dass eine implizite Konvertierung existiert, und dies gilt für eine List(Of Irgendwas) nicht.
Was auch besser ist, sonst könntest Du z. B. aus einem Vogel einen Affen machen,
wenn Du Dir für BaseObject einsetzt "Tier" und die konkrete Klasse "Vogel", "Affe" wären.
Nur dem Affen das Fliegen beizubringen ist damit nicht möglich ;-)Meine Frage gestern zielte mehr darauf ab, was Du mit der Liste einer Liste lösen möchtest.
Denn für Business Objekte sehe ich direkt keine Notwendigkeit, z. B. Kunden und Aufträge zusammen zufassen.Helfen könnte man sich mit Dingen wie MakeGenericType.
Nicht erreichen kann damit aber, dass bereits zur Kompilierzeit typsichere Klassen existieren,
denn dem steht obiges entgegen.
Das fällt in etwa in die Kategorie, wie es Simulated Covariance for .NET Generics beschreibt.Gruß Elmar
- Als Antwort markiert Heslacher Mittwoch, 24. August 2011 09:02
-
Hallo Hannes,
ich kann nur betonen, es funktioniert nicht.
Ok. Ich hatte es in der Zwischenzeit schon anders gelöst, die Frage hat mich aber weiter interessiert.
Es ist erforderlich, dass eine implizite Konvertierung existiert, und dies gilt für eine List(Of Irgendwas) nicht.
Was auch besser ist, sonst könntest Du z. B. aus einem Vogel einen Affen machen,
wenn Du Dir für BaseObject einsetzt "Tier" und die konkrete Klasse "Vogel", "Affe" wären.
Nur dem Affen das Fliegen beizubringen ist damit nicht möglich ;-)Bring mir den Affen und ich bring dem Affen das fliegen bei. Ich wohne im 4. Stock ;-)
Meine Frage gestern zielte mehr darauf ab, was Du mit der Liste einer Liste lösen möchtest.
Denn für Business Objekte sehe ich direkt keine Notwendigkeit, z. B. Kunden und Aufträge zusammen zufassen.Helfen könnte man sich mit Dingen wie MakeGenericType.
Nicht erreichen kann damit aber, dass bereits zur Kompilierzeit typsichere Klassen existieren,
denn dem steht obiges entgegen.
Das fällt in etwa in die Kategorie, wie es Simulated Covariance for .NET Generics beschreibt.Gruß Elmar
Die Frage bezog sich nicht explicit auf Business Objekte im herkömmlichen Sinn.Bei der Anwendung die ich gerade erstelle müssen Kunden Ordner und darin befindliche Ordner und Dateien bei Änderung der Kundendaten verschoben werden.
Sollte dies nicht möglich sein, da diese z.B. momentan in Gebrauch sind, werden die Ordner- und Dateinamen in der Datenbank gespeichert.Dies geschieht durch:
1. Eintrag eines "Jobs" mit dem letzten zu verschiebenden Ordner ( also der oberste Kundenordner )
2. Eintrag des Quell- und Zielordners und des Dateinamens für jede zu verschiebende Datei/Ordner.
Diese "Jobs" sollen dann von einem Programm abgearbeitet werden, also das erneute versuchte Verschieben der Dateien und Ordner.
Dafür wollte ich alle "Jobs" in eine Liste packen. Diese Jobs sind aber ja auch wieder eine Liste von den Einträgen der Quell- und Zielordnern und den Dateinamen. Darum war mein erster Ansatz der oben beschriebene mit der ListeDerListe.
Ich hatte allerdings nicht weiter darüber nachgedacht, ob ich dies überhaupt in dieser Form noch einmal gebrauchen kann. Da ich zu dem Schluss kam, dass das nicht der Fall ist, habe ich diesen Ansatz aufgegeben und habe das Problem anders gelöst.
Das grundlegende Interesse, ob dies generell möglich ist, war aber geblieben. Durch Deine Antwort habe ich mal wieder was gelernt :-)
Danke
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/