none
Generische MustInherit Klasse RRS feed

  • 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/
    Montag, 22. August 2011 08:01

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 FAQ

    Die 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 Class

    womit 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
    Dienstag, 23. August 2011 09:04
    Beantworter
  • 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
    Mittwoch, 24. August 2011 07:44
    Beantworter

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 FAQ

    Die 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 Class

    womit 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
    Dienstag, 23. August 2011 09:04
    Beantworter
  • 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/
    Dienstag, 23. August 2011 10:22
  • 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
    Mittwoch, 24. August 2011 07:44
    Beantworter
  • 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/
    Mittwoch, 24. August 2011 09:02