Guida al Visual Basic .NET - Le Proprieta Parte I
Cerca
 











Guida al Visual Basic .NET

Capitolo 20° - Le Proprieta Parte I

A cura di: Totem

<< Precedente Prossimo >>

Le proprietà sono una categoria di membri di classe molto importante, che useremo molto spesso da qui in avanti. Non è possibile definirne con precisione la natura: esse sono una via di mezzo tra metodi (procedure o funzioni) e campi (variabili dichiarate in una classe). In genere, si dice che le proprietà siano "campi intelligenti", poiché il loro ruolo consiste nel mediare l'interazione tra codice esterno alla classe e campo di una classe. Esse si "avvolgono" intorno a un campo (per questo motivo vengono anche chiamate wrapper, dall'inglese wrap = impacchettare) e decidono, tramite codice scritto dal programmatore, quali valori siano leciti per quel campo e quali no - stile buttafuori, per intenderci. La sintassi con cui si dichiara una proprietà è la seguente:
Property [Nome]() As [Tipo]
    Get
        '...
        Return [Valore restituito]
    End Get
    Set(ByVal value As [Tipo])
        '...
    End Set
End Property 
Ora, questa sintassi, nel suo insieme, è molto diversa da tutto ciò che abbiamo visto fino ad ora. Tuttavia, guardando bene, possiamo riconoscere alcuni blocchi di codice e ricondurli ad una categoria precedentemente spiegata:
  • La prima riga di codice ricorda la dichiarazione di una variabile;
  • Il blocco Get ricorda una funzione; il codice ivi contenuto viene eseguito quando viene richiesto il valore della proprietà;
  • Il blocco Set ricorda una procedura a un parametro; il codice ivi contenuto viene eseguito quando un codice imposta il valore della proprietà.
Da quello che ho appena scritto sembra proprio che una proprietà sia una variabile programmabile, ma allora da dove si prende il valore che essa assume? Come ho già ripetuto, una proprietà media l'interazione tra codice esterno e campo di una classe: quindi dobbiamo stabilire un modo per collegare la proprietà al campo che ci interessa. Ecco un esempio:
Module Module1
    Class Example
        'Campo pubblico di tipo Single.
        Public _Number As Single

        'La proprietà Number media, in questo caso, l'uso
        'del campo _Number.
        Public Property Number() As Single
            Get
                'Quando viene chiesto il valore di Number, viene
                'restituito il valore della variabile _Number. Si
                'vede che la proprietà non fa altro che manipolare
                'una variabile esistente e non contiene alcun
                'dato di per sé
                Return _Number
            End Get
            Set(ByVal value As Single)
                'Quando alla proprietà viene assegnato un valore,
                'essa modifica il contenuto di _Number impostandolo
                'esattamente su quel valore
                _Number = value
            End Set
        End Property
    End Class

    Sub Main()
        Dim A As New Example()

        'Il codice di Main sta impostando il valore di A.Number.
        'Notare che una proprietà si usa esattamente come una
        'comunissima variabile di istanza.
        'La proprietà, quindi, richiama il suo blocco Set come
        'una procedura e assegna il valore 20 al campo A._Number
        A.Number = 20
        
        'Nella prossima riga, invece, viene richiesto il valore
        'di Number per poterlo scrivere a schermo. La proprietà
        'esegue il blocco Get come una funzione e restituisce al
        'chiamante (ossia il metodo/oggetto che ha invocato Get,
        'in questo caso Console.WriteLine) il valore di A._Number
        Console.WriteLine(A.Number)
        
        'Per gli scettici, facciamo un controllo per vedere se
        'effettivamente il contenuto di A._Number è cambiato.
        'Potrete constatare che è uguale a 20.
        Console.WriteLine(A._Number)

        Console.ReadLine()
    End Sub
End Module 
Per prima cosa bisogna subito fare due importanti osservazioni:
  • Il nome della proprietà e quello del campo a cui essa sovrintende sono molto simili. Questa similarità viene mentenuta per l'appunto a causa dello stretto legame che lega proprietà e campo. È una convenzione che il nome di un campo mediato da una proprietà inizi con il carattere underscore ("_"), oppure con una di queste combinazioni alfanumeriche: "p_", "m_". Il nome usato per la proprietà sarà, invece, identico, ma senza l'underscore iniziale, come in questo esempio.
  • Il tipo definito per la proprietà è identico a quello usato per il campo. Abbastanza ovvio, d'altronde: se essa deve mediare l'uso di una variabile, allora anche tutti i valori ricevuti e restituiti dovranno essere compatibili.


La potenza nascosta delle proprietà

Arrivati a questo punto, uno potrebbe pensare che, dopotutto, non vale la pena di sprecare spazio per scrivere una proprietà quando può accedere direttamente al campo. Bene, se c'è veramente qualcuno che leggendo quello che ho scritto ha pensato veramente a questo, può anche andare a compiangersi in un angolino buio. XD Scherzi a parte, l'utilità c'è, ma spesso non si vede. Prima di tutto, iniziamo col dire che se un campo è mediato da una proprietà, per convenzione (ma anche per buon senso), deve essere Private, altrimenti lo si potrebbe usare indiscriminatamente senza limitazioni, il che è proprio quello che noi vogliamo impedire. A questo possiamo anche aggiungere una considerazione: visto che abbiamo la possibilità di farlo, aggiungendo del codice a Get e Set, perchè non fare qualche controllo sui valori inseriti, giusto per evitare errori peggiori in un immediato futuro? Ammettiamo di avere la nostra bella classe:
Module Module1
    'Questa classe rappresenta un semplice sistema inerziale,
    'formato da un piano orizzontale scabro (con attrito) e
    'una massa libera di muoversi su di esso
    Class InertialFrame
        Private _DynamicFrictionCoefficient As Single
        Private _Mass As Single
        Private _GravityAcceleration As Single

        'Coefficiente di attrito radente (dinamico), 
        Public Property DynamicFrictionCoefficient() As Single
            Get
                Return _DynamicFrictionCoefficient
            End Get
            Set(ByVal value As Single)
                _DynamicFrictionCoefficient = value
            End Set
        End Property

        'Massa, m
        Public Property Mass() As Single
            Get
                Return _Mass
            End Get
            Set(ByVal value As Single)
                _Mass = value
            End Set
        End Property

        'Accelerazione di gravità che vale nel sistema, g
        Public Property GravityAcceleration() As Single
            Get
                Return _GravityAcceleration
            End Get
            Set(ByVal value As Single)
                _GravityAcceleration = value
            End Set
        End Property

        'Calcola e restituisce la forza di attrito che agisce
        'quando la massa è in moto
        Public Function CalculateFrictionForce() As Single
            Return (Mass * GravityAcceleration) * DynamicFrictionCoefficient
        End Function

    End Class

    Sub Main()
        Dim F As New InertialFrame()

        Console.WriteLine("Sistema inerziale formato da:")
        Console.WriteLine(" - Un piano orizzontale e scabro;")
        Console.WriteLine(" - Una massa variabile.")
        Console.WriteLine()

        Console.WriteLine("Inserire i dati:")
        Console.Write("Coefficiente di attrito dinamico = ")
        F.DynamicFrictionCoefficient = Console.ReadLine
        Console.Write("Massa (Kg) = ")
        F.Mass = Console.ReadLine
        Console.Write("Accelerazione di gravità (m/s2) = ")
        F.GravityAcceleration = Console.ReadLine

        Console.WriteLine()
        Console.Write("Attrito dinamico = ")
        Console.WriteLine(F.CalculateFrictionFo
<< Precedente Prossimo >>
 

Creative Commons License
Il layout di questo sito è concesso sotto licenza Creative Commons.
Per maggiori informazioni sulle licenze dei contenuti del sito, clicca.