9 messaggi dal 24 novembre 2014
Ok, grazie. (Volume "Visual Basic 2012 - Guida completa per lo sviluppatore")
Vorrei fare prove sull'inizializzazione di "Oggetti, Array e Collezioni" (pag. 63) ma mi sono subito impantanato.
Volendo riprodurre l'esempio a pag. 63 (esempio 4.8) ho creato un programma costituito da un unico Form con l'intenzione, in seguito, di dichiarare proprietà. Ecco l'intero codice:

Public Class Form1
Public Class Persona
Dim Cognome, Nome As String
Dim Data As Integer
Dim X1 As New Persona With {.Cognome = "Pippo", .Nome = "Pluto", .Data = 30}
End Class
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim Cognome, Nome As String
Dim Data As Integer
Dim X2 As New Persona With {.Cognome = "Paperino", .Nome = "Topolino", .Data = 30}
X2.Cognome = "alfa"
' eccetera
End Sub
End Class

Compaiono 4 errori ("Errore 2 '_2014_11_24_Prova_B.Form1.Persona.Nome' non è accessibile in questo contesto perché è 'Private'

Ho provato a modificare Private con Public a creare a parte una Class (prima di Public Class Form1), ma mi segnala sempre errori.

Lo scopo che voglio raggiungere è di definire, oltre a X1, altre variabili (X2, X3...) da gestire in seguito tramite pulsanti, TextBox e altri strumenti.

Dove sbaglio?
Modificato da Dario_VB il 24 novembre 2014 17.06 -
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao Dario e benvenuto nel forum!
per risolvere il problema, iniziamo dall'errore che il compilatore ti ha segnalato.

Persona.Nome non è accessibile in questo contesto perché è 'Private'


Hai definito una proprietà "Nome" all'interno della classe "Persona", ma per qualche motivo è impossibile usarla. Il compilatore dice che non è "accessibile", e infatti ha ragione, perché quando dichiari un membro di una classe con la parola chiave Dim è come aver usato il modificatore di accesso "Private". Quando il membro di una classe è "Private", è accessibile solo da altri membri della classe stessa.

Proprio come nel mondo reale, una Persona possiede informazioni che vuole rendere pubbliche (come il suo nome e cognome), altre che vuole tenere private (come l'ammontare del conto in banca) e altre che vuole condividere solo con i parenti stretti (come il suo stato di salute).

Dato che il nome e cognome devono essere pubbliche, andiamo a dichiararle come tali
Public Class Persona
  Public Property Nome As String 
  Public Property Cognome As String 
End Class

A questo punto, dal metodo Form1_Load, crea una o più istanze di Persona e valorizzarne le proprietà Nome e Cognome. Ora è possibile perché le abbiamo rese pubbliche.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim persona1 As New Persona With {.Nome = "Paperino", .Cognome = "Paolino"}
Dim persona2 As New Persona With {.Nome = "Pico", .Cognome = "De' Paperis"}
' eccetera
End Sub

A proposito, hai visto che ho usato la parola chiave Property nel dichiarare Nome e Cognome?
Una proprietà ti consente di decidere se l'utente della classe Persona può scriverla, leggerla o fare entrambe le cose. Oltretutto puoi anche mettere del codice per regolare le operazioni di lettura e scrittura.
Un campo, invece, non ti dà questo genere di controllo e perciò lo si preferisce usare solo con il modificatore Private, per impedire che gli utenti della classe possano modificarlo indiscriminatamente.

Ti faccio un esempio per spiegare questa possibilità. Nel mondo reale, il Nome di una Persona non può essere cambiato: le viene assegnato quando nasce e resta tale per tutta la vita (non è sempre vero ma per il momento facciamo finta che sia così). Di conseguenza, possiamo fare il refactoring della classe Persona, ovvero modellarla affinché rifletta più accuratamente il caso reale.

Public Class Persona
  'Questo è il campo privato che conterrà il nome
  Private _nome As String
  'E questa è la proprietà che ne regola l'accesso
    Public Property Nome() As String
    'In lettura, restituisco il valore così com'è
        Get
            Return _nome
        End Get
    'Ma consento la scrittura solo alla classe stessa
    'In modo che il nome non possa essere cambiato in maniera indiscriminata dall'esterno
        Private Set
            _nome = value
        End Set
    End Property

  'Idem per il cognome
    Private _cognome As String
    Public Property Cognome() As String
        Get
            Return _cognome
        End Get

        Private Set
            _cognome = value
        End Set
    End Property

    Public Sub New(nome As String, cognome As String)
    'Copio i valori sulle mie proprietà
    'Posso farlo perché, anche se Nome e Cognome sono privati
    'li sto scrivendo da codice contenuto nella classe stessa
    Me.Nome = nome
    Me.Cognome = cognome
    End Sub
End Class

E la istanzi così:
Dim persona As New Persona("Paperino", "Paolino")

Creata l'istanza, non sarà più possibile modificare il nome e il cognome della persona, perché i loro Set sono privati.

Ora che abbiamo visto i due casi (scrittura pubblica e privata), decidi tu quale adottare. Se stai realizzando un form di inserimento dati, allora probabilmente vuoi che Nome e Cognome siano reimpostabili a piacimento, come nel primo esempio.
Se invece stai realizzando un'applicazione per l'anagrafe, allora probabilmente ti è richiesto un certo rigore e scegli il secondo esempio per impedire che nomi e cognomi possano essere cambiati così facilmente. La scelta dipende dalla situazione che stai cercando di rappresentare con il software.

Un'ultima cosa: è preferibile che la classe Persona sia definita al di fuori del Form1, quindi mettila in un altro file del tuo progetto, chiamato ad esempio Persona.vb.

ciao,
Moreno
Modificato da BrightSoul il 26 novembre 2014 22.17 -

Enjoy learning and just keep making
9 messaggi dal 24 novembre 2014
Sono commosso, sul serio. Avevo chiesto solo un paio di righe di codice e ho ricevuto, invece, un vero e proprio trattato completo, chiaro e - soprattutto - risolutore del mio problema. Una condotta molto professionale, difficilmente riscontrabile in altri Forum di settore.
Grazie ancora e... alla prossima!

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.