vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Top-Preis! AP-Access-Tools-CD Volume 1  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
Re: Generischen Typen umwandeln 
Autor: IIIIIChrisIIIII
Datum: 01.09.11 09:02

Hallo!



Man könnte aber beispielsweise die Set-Methoden (zum Ändern der Properties) in der Klasse implementieren (da dort die Kovarianz nicht gilt), nicht jedoch im Interface vorgeben.


Genau so habe ich es jetzt gemacht und es ist perfekt! Zuerst dachte ich, dass es in meinem Fall so nicht ginge, weil ich die Property O setzten müsste. Dem ist aber nicht so. Denn wenn ich über die Schnittstelle zugreife, weiß ich ja nicht, von welchem Typ TA ist. Ergo könnte ich diesen Wert eh nicht setzten. Innerhalb meiner Implementierung habe ich dann konkrete Set-Methoden für die Properties, die einen Parameter vom Typ TA erwarten. Somit ist alles "schön" und ich muss auch nicht innerhalb der Implementierung hin und her casten.

Vielen Dank noch einmal für deine Hilfe! Hat mir SEHR weitergeholfen !

Beitrag wurde zuletzt am 01.09.11 um 09:03:34 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Generischen Typen umwandeln 
Autor: IIIIIChrisIIIII
Datum: 31.08.11 16:23

Hallo,

ich habe mal wieder ein ausgefallenes Problem. Hier erstmal der Code:
Public Class Form1
 
	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
  System.EventArgs) Handles Button1.Click
		Dim O As Object = New Test(Of X, Button)
		Dim T As ITest(Of Object, Windows.Forms.Control) = DirectCast(O, ITest(Of _
  Object, Windows.Forms.Control))
	End Sub
End Class
 
Public Interface ITest(Of TA, TB As Windows.Forms.Control)
 
End Interface
 
Public Class Test(Of TA, TB As Windows.Forms.Control)
	Implements ITest(Of TA, TB)
 
End Class
 
Public Class X
 
End Class
Wenn ich den Button klicke, erhalte ich in der zweiten Zeile des EventHandlers Button1_Click folgende Fehlermeldung:
Das Objekt des Typs "WindowsApplication1.Test`2[WindowsApplication1.X,System.Windows.Forms.Button]" kann nicht in Typ "WindowsApplication1.ITest`2[System.Object,System.Windows.Forms.Control]" umgewandelt werden.

Wahrscheinlich castet er nicht tief weswegen es zum obigen Fehler kommt. Kennt jemand eine Möglichkeit das doch zu umgehen?

Vielen Dank,
Chris
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Generischen Typen umwandeln 
Autor: Preisser
Datum: 31.08.11 18:47

Hallo,

Generika in Klassen sind standardmäßig weder ko- noch kontravariant, da sonst beispielsweise soetwas möglich wäre:
Option Strict On
Public Class Test(Of T)
    Public Param As T
End Class
 
'' irgendwo im Code:
    Public Sub Testen()
        Dim a As Test(Of Bitmap) = New Test(Of Bitmap)()
        Dim b As Test(Of Object) = a
        b.Param = "Hi" 'String ist ein Untertyp von Object
        Dim bmp As Bitmap = a.Param 'a.Param ist vom Typ Bitmap
    End Sub
Allerdings kann man bei Interfaces festlegen, dass Typparameter ko- oder kontravariant sein sollen (siehe hier), durch Angabe von "Of Out T" (Kovarianz) oder "Of In T" (Kontravarianz). Allerdings darf die Verwendung der Typparameter in Methoden der Klasse diese Einschränkung dann nicht verletzen.

Beitrag wurde zuletzt am 31.08.11 um 19:08:01 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Generischen Typen umwandeln 
Autor: IIIIIChrisIIIII
Datum: 31.08.11 19:12

Hallo Preisser,

vielen Dank für deine Antwort! Das mit den ko oder kontravarianten Typenparametern ist mir nach meinem Post auch eingefallen, kommt aber in meinem konkreten Fall nicht vor. Ich hatte bei meinem Code der Einfachheitshalber einige Sachen rausgelassen/vergessen. So ist es vollständig:
Public Class Form1
 
	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
  System.EventArgs) Handles Button1.Click
		Dim Obj As Object = New ExtTest()
		Dim T As ITest(Of Object, Control) = DirectCast(Obj, ITest(Of Object, _
  Control))
	End Sub
End Class
 
 
 
#Region "Test1"
Public Interface ITest(Of TA, TB As Windows.Forms.Control)
 
	Property O As TA
	Property Ctrl As TB
 
End Interface
 
Public Class Test(Of TA, TB As Windows.Forms.Control)
	Implements ITest(Of TA, TB)
 
	Public Property Ctrl As TB Implements ITest(Of TA, TB).Ctrl
		Get
 
		End Get
		Set(ByVal value As TB)
 
		End Set
	End Property
 
	Public Property O As TA Implements ITest(Of TA, TB).O
		Get
 
		End Get
		Set(ByVal value As TA)
 
		End Set
	End Property
 
End Class
 
Public Class ExtTest
	Inherits Test(Of X, Button)
 
End Class
 
 
Public Class X
 
End Class
 
#End Region
Dadurch wird klar, dass ich weder ko noch kontravarianz verwenden kann.
Ich verstehe zwar den Grund, wieso der compiler Meckert - dein Beispiel ist einleuchtend. Aber leider kann ich dadurch kein Generics mehr verwenden.
Vielleicht etwas zum Hintergrund: Ich habe ein Programm, dass über Reflection alle Implementierungen der besagten Schnittstelle instanziert. Die Typenparameter für die Schnittstelle sind einmal der Typ für ein Settings-Objekt und der zweite für die GUI (also Control).
Erstelle ich ein Projekt mit einer neue Klasse, die diese Schnittstelle implmeneitiert kann ich innerhalb der Klasse direkt auf die Settings und die GUI (die sich logischerweise auch spezifisch im gleichen Projekt befinden) zugreifen (also über die Properties).
Von außen dachte ich könnte ich immer auf Object / Control zugreifen.
Nun muss ich die Generics entfernen und die Properties Settings und GUI der Schnittstelle auf Object und Control ändern, wodurch beim Implementieren einer solchen Schnittstelle ich intern immer casten muss. Die Generic-Variante fand ich "schöner" ;).

Für andere Tipps bin ich sehr dankbar.
Vielen Dank noch einmal!
Chris

Beitrag wurde zuletzt am 31.08.11 um 19:15:32 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Generischen Typen umwandeln 
Autor: Preisser
Datum: 31.08.11 21:38

Hallo,

wenn sich die beiden Properties der Klasse/Interface später nicht mehr verändern (readonly), könntest du Kovarianz verwenden, sodass man über eine weniger spezifische Typvariable darauf zugreifen kann.
Dann müssten die Parameter allerdings schon im Konstruktur der Klasse übergeben werden.
z.B.
Public Interface ITest(Of Out TA, Out TB As Windows.Forms.Control)
    ReadOnly Property O As TA
    ReadOnly Property Ctrl As TB
End Interface
 
Public Class Test(Of TA, TB As Windows.Forms.Control)
    Implements ITest(Of TA, TB)
    Private ReadOnly _Ctrl As TB
    Private ReadOnly _O As TA
 
    Public Sub New(O As TA, Ctrl As TB)
        Me._O = O
        Me._Ctrl = Ctrl
    End Sub
 
    Public ReadOnly Property Ctrl As TB Implements ITest(Of TA, TB).Ctrl
        Get
            Return _Ctrl
        End Get
    End Property
 
    Public ReadOnly Property O As TA Implements ITest(Of TA, TB).O
        Get
            Return _O
        End Get
    End Property
 
End Class
Dann könnte man sowas schreiben, ohne dass der Compiler meckert:
        Dim i1 As ITest(Of String, TextBox) = New Test(Of String, TextBox)( _
          "Test", New TextBox())
        Dim i2 As ITest(Of Object, Control) = i1
Wenn sich die Properties allerdings ändern können sollen, geht dies nicht so direkt (zumindest für den selben Typparameter), da (soweit ich weiß) bei Parametern, die einer Methode übergeben werden, nur Kontravarianz verwendet werden kann, jedoch beim Rückgabewert nur Kovarianz.
Man könnte aber beispielsweise die Set-Methoden (zum Ändern der Properties) in der Klasse implementieren (da dort die Kovarianz nicht gilt), nicht jedoch im Interface vorgeben.

Beitrag wurde zuletzt am 31.08.11 um 22:15:27 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel