Newsgroup: it.comp.lang.visual-basic
Titolo: Architettura interna di ADO.Net

La classe DBConnection fornisce il metodo
Public Function CreateCommand As DbCommand
 
Mentre la classe derivata OleDbConnection fornisce il metodo
Public Function CreateCommand As OleDbCommand
 
In questo modo, la classe derivata OleDbConnection rispetta in qualche modo il pattern della classe base, ma fornendo membri più tipizzati.
 
Quello che non capisco è come si faccia ad ottenere una tale tipizzazione continuando però a rispettare i vincoli di eredità.
Infatti tra i membri di OleDbConnection  non risulta più alcuna traccia del metodo CreateCommand As DbCommand ereditato da DBConnection.
 
Con quale tecnica secondo voi si ottiene questo risultato? Shadowing?

 Con quale tecnica secondo voi si ottiene questo risultato? Shadowing?
 
Un sistema è questo:
Nella classe base, dividere il singolo metodo in due, uno public e uno protected
 
Protected Overridable Function OnCreateXX() As BaseXX
    Return New BaseXX()
End Function
Public Function CreateXX() As BaseXX
    Return OnCreateXX()
End Function
 
Nella derivata, fare override del primo, e overloads del secondo
 
Protected Overrides Function OnCreateXX() As BaseXX
    Return New DerivataXX()
End Function
Public Overloads Function CreateXX() As DerivataXX 'nota il cambio di tipo
    Return DirectCast(OnCreateXX(), DerivataXX)
End Function
 
Considerato che Common.DBConnection espone i metodi 
 
Protected MustOverride Function CreateDbCommand() As DbCommand
e
Public Function CreateCommand() As DbCommand
 
non escluderei sia stato usato proprio questo tipo di approccio

Ciao, grazie della risposta.
A dire il vero non capisco la necessita del metodo OnCreateXX().
Secondo me basta definire nella classe base
 
Public Function CreateXX() As BaseXX
    Return New BaseXX()
End Function
 
e poi, nella classe derivata
 
Public Overloads Function CreateXX() As DerivataXX
    Return New DerivataXX()
End Function
 
Però questo secondo me non spiega, nel caso della classe OleDbConnection, che fine abbia fatto il metodo CreateCommand As DbCommand.
 
In altre parole, secondo me, nella classe derivata dovrebbero risultare visibili, sia il metodo
 
Public Overloads Function CreateXX() As DerivataXX
 
che il metodo originale
 
Public Function CreateXX() As BaseXX
 
O sbaglio?

 End Function
 
No, non basta... se passi un istanza della classe derivata a funzioni che hanno come parametro la classe base, e da lì chiami CreateXX, non viene eseguito il codice che ti aspetti 
 
Immagina di avere una funzione così
 
    Private Sub TestFunction(db As BaseConnection)
        Dim command As BaseCommand = db.CreateCommand
        Debug.WriteLine(command.TestMe)
    End Sub
 
e chiamarla con
        TestFunction(New BaseConnection)
        TestFunction(New DerivedConnection)
 
Ora, prendi prima questo set di classi (
http://pastebin.com/irVuf9V9
) fatte come dici tu, e poi quest'altro (
http://pastebin.com/8SVg2cMf
) fatte come dico io, e vedrai che il risultato cambia.
 
E' 'override' che fa funzionare il tutto, ma non lo puoi applicare se la funzione cambia il tipo di ritorno, da cui la soluzione di separare in due protected/public

Era proprio il passaggio che mi mancava. Grazie mille, mi hai fatto fare un passo avanti. :-)
 
Adesso entro in modalità filosofico/rompiscatole, ma puoi benissimo non rispondere.
 
Non sarebbe stato possibile per i creatori del linguaggio, consentire che l'override di un metodo potesse restituire tipi derivati già nella firma?
 
Nel caso precedente, ad esempio, sarebbe bastato scrivere
 
'Classe base
Public Overridable Function CreateCommand() As BaseCommand
    Return New BaseCommand()
End Function
 
'Classe derivata
Public Overrides Function CreateCommand() As DerivedCommand
    Return New DerivedCommand()
End Function
 
Ovviamente, non è che il problema sia quello di scrivere qualche riga in più. Più che altro è per capire le motivazioni di fondo.

 Non sarebbe stato possibile per i creatori del linguaggio, consentire che l'override di un metodo potesse restituire tipi derivati già nella firma?
 
Si, è possibile, ci sono liguaggi che lo supportano
https://en.wikipedia.org/wiki/Covariant_return_type
 
 
Un altro sistema, oltre a quello sopra, per ottenerlo in .NET e' tramite Generic o Interfacce


Ok, grazie ancora.