[C#] Qual è la differenza tra un campo e una proprietà?


Answers

Proprietà espone campi. I campi dovrebbero (quasi sempre) essere mantenuti privati ​​in una classe e accessibili tramite le proprietà get e set. Le proprietà forniscono un livello di astrazione che consente di modificare i campi senza influire sul modo esterno a cui accedono le cose che usano la classe.

public class MyClass
{
    // this is a field.  It is private to your class and stores the actual data.
    private string _myField;

    // this is a property. When accessed it uses the underlying field,
    // but only exposes the contract, which will not be affected by the underlying field
    public string MyProperty
    {
        get
        {
            return _myField;
        }
        set
        {
            _myField = value;
        }
    }

    // This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
    // used to generate a private field for you
    public int AnotherProperty{get;set;} 
}

@Kent sottolinea che le proprietà non sono richieste per incapsulare i campi, potrebbero eseguire un calcolo su altri campi o servire ad altri scopi.

@GSS sottolinea che puoi anche fare altra logica, come la convalida, quando si accede a una proprietà, un'altra caratteristica utile.

Question

In C #, cosa rende un campo diverso da una proprietà e quando dovrebbe essere usato un campo al posto di una proprietà?




Se intendi utilizzare le primitive del thread, sei obbligato a utilizzare i campi. Le proprietà possono rompere il codice filettato. A parte ciò, ciò che ha detto è corretto.




Le proprietà supportano l'accesso asimmetrico, ovvero puoi avere un getter e un setter o solo uno dei due. Allo stesso modo le proprietà supportano l'accessibilità individuale per getter / setter. I campi sono sempre simmetrici, ovvero puoi sempre ottenere e impostare il valore. Eccezione a ciò sono i campi di sola lettura che ovviamente non possono essere impostati dopo l'inizializzazione.

Le proprietà possono funzionare per un tempo molto lungo, avere effetti collaterali e possono anche generare eccezioni. I campi sono veloci, senza effetti collaterali e non generano mai eccezioni. A causa di effetti collaterali, una proprietà può restituire un valore diverso per ogni chiamata (come potrebbe essere il caso per DateTime.Ora, ad esempio DateTime.Ora non è sempre uguale a DateTime.Now). I campi restituiscono sempre lo stesso valore.

I campi possono essere usati per i parametri out / ref, le proprietà no. Le proprietà supportano la logica aggiuntiva, che potrebbe essere utilizzata per implementare il caricamento lazy tra le altre cose.

Le proprietà supportano un livello di astrazione incapsulando qualsiasi cosa significhi ottenere / impostare il valore.

Utilizzare le proprietà nella maggior parte / tutti i casi, ma cercare di evitare effetti collaterali.




Think about it : You have a room and a door to enter this room. If you want to check how who is coming in and secure your room, then you should use properties otherwise they won't be any door and every one easily come in w/o any regulation

class Room {
   public string sectionOne;
   public string sectionTwo;
}

Room r = new Room();
r.sectionOne = "enter";

People is getting in to sectionOne pretty easily, there wasn't any checking

class Room 
{
   private string sectionOne;
   private string sectionTwo;

   public string SectionOne 
   {
      get 
      {
        return sectionOne; 
      }
      set 
      { 
        sectionOne = Check(value); 
      }
   }
}

Room r = new Room();
r.SectionOne = "enter";

Now you checked the person and know about whether he has something evil with him




DIFFERENZE - USI (quando e perché)

Un campo è una variabile dichiarata direttamente in una classe o in una struttura. Una classe o una struttura possono avere campi di istanza o campi statici o entrambi. In genere, è necessario utilizzare i campi solo per le variabili che dispongono di accessibilità privata o protetta . I dati che la tua classe espone al codice cliente dovrebbero essere forniti attraverso metodi, proprietà e indicizzatori. Utilizzando questi costrutti per l'accesso indiretto ai campi interni, è possibile proteggersi da valori di input non validi.

Una proprietà è un membro che fornisce un meccanismo flessibile per leggere, scrivere o calcolare il valore di un campo privato. Le proprietà possono essere utilizzate come se fossero membri di dati pubblici, ma in realtà sono metodi speciali chiamati accessor . Ciò consente di accedere facilmente ai dati e contribuisce a promuovere la sicurezza e la flessibilità dei metodi . Le proprietà consentono a una classe di esporre un metodo pubblico per ottenere e impostare valori, nascondendo il codice di implementazione o di verifica. Una proprietà di accesso get viene utilizzata per restituire il valore della proprietà e un accessor set viene utilizzato per assegnare un nuovo valore.




Properties are used to expose field. They use accessors(set, get) through which the values of the private fields can be read, written or manipulated.

Properties do not name the storage locations. Instead, they have accessors that read, write, or compute their values.

Using properties we can set validation on the type of data that is set on a field.

For example we have private integer field age on that we should allow positive values since age cannot be negative.

We can do this in two ways using getter and setters and using property.

 Using Getter and Setter

    // field
    private int _age;

    // setter
    public void set(int age){
      if (age <=0)
       throw new Exception();

      this._age = age;
    }

    // getter
    public int get (){
      return this._age;
    }

 Now using property we can do the same thing. In the value is a key word

    private int _age;

    public int Age{
    get{
        return this._age;
    }

    set{
       if (value <= 0)
         throw new Exception()
       }
    }

Auto Implemented property if we don't logic in get and set accessors we can use auto implemented property.

When u se auto-implemented property compiles creates a private, anonymous field that can only be accessed through get and set accessors.

public int Age{get;set;}

Abstract Properties An abstract class may have an abstract property, which should be implemented in the derived class

public abstract class Person
   {
      public abstract string Name
      {
         get;
         set;
      }
      public abstract int Age
      {
         get;
         set;
      }
   }

// overriden something like this
// Declare a Name property of type string:
  public override string Name
  {
     get
     {
        return name;
     }
     set
     {
        name = value;
     }
  }

We can privately set a property In this we can privately set the auto property(set with in the class)

public int MyProperty
{
    get; private set;
}

You can achieve same with this code. In this property set feature is not available as we have to set value to field directly.

private int myProperty;
public int MyProperty
{
    get { return myProperty; }
}



Additional info: By default, get and set accessors are as accessible as the property itself. You can control/restrict accessor accessibility individually (for get and set) by applying more restrictive access modifiers on them.

Esempio:

public string Name
{
    get
    {
        return name;
    }
    protected set
    {
        name = value;
    }
}

Here get is still publicly accessed (as the property is public), but set is protected (a more restricted access specifier).




I principi di programmazione orientati agli oggetti dicono che i meccanismi interni di una classe dovrebbero essere nascosti al mondo esterno. Se esponi un campo, in sostanza stai esponendo l'implementazione interna della classe. Quindi avvolgiamo campi con Proprietà (o metodi nel caso di Java) per darci la possibilità di cambiare l'implementazione senza infrangere il codice a seconda di noi. Vedere come possiamo inserire la logica nella proprietà ci consente anche di eseguire la logica di convalida ecc. Se ne abbiamo bisogno. C # 3 ha la nozione, forse confusa, di autoproprietà. Questo ci permette di definire semplicemente la proprietà e il compilatore C # 3 genererà il campo privato per noi.

public class Person
{
   private string _name;

   public string Name
   {
      get
      {
         return _name;
      }
      set
      {
         _name = value;
      }
   }
   public int Age{get;set;} //AutoProperty generates private field for us
}



I campi sono variabili membro ordinarie o istanze membro di una classe. Le proprietà sono un'astrazione per ottenere e impostare i loro valori . Le proprietà sono anche denominate accessors perché offrono un modo per cambiare e recuperare un campo se si espone un campo nella classe come privato. In generale, è necessario dichiarare le proprie variabili membro private, quindi dichiarare o definire proprietà per esse.

  class SomeClass
  {
     int numbera; //Field

     //Property 
    public static int numbera { get; set;}

  }



Tecnicamente, non penso che ci sia una differenza, perché le proprietà sono solo wrapper attorno ai campi creati dall'utente o creati automaticamente dal compilatore. Lo scopo delle proprietà è quello di rafforzare l'incapsulamento e offrire una funzionalità simile a un metodo leggero. È semplicemente una cattiva pratica dichiarare i campi come pubblici, ma non ha alcun problema.




La seconda domanda qui, "quando un campo dovrebbe essere usato al posto di una proprietà?", Viene solo brevemente accennata in questa altra risposta e anche questa , ma non molto, in dettaglio.

In generale, tutte le altre risposte sono chiare sul buon design: preferiscono esporre le proprietà oltre i campi di esposizione. Mentre probabilmente non ti troverai regolarmente a dire "wow, immagina quante cose peggiori sarebbero se avessi fatto di questo un campo invece di una proprietà", è molto più raro pensare a una situazione in cui potresti dire "wow, grazie a Dio ho usato un campo qui invece di una proprietà ".

Ma c'è un vantaggio che i campi hanno sulle proprietà, e questa è la loro capacità di essere usati come parametri "ref" / "out". Supponiamo di avere un metodo con la seguente firma:

public void TransformPoint(ref double x, ref double y);

e supponiamo che tu voglia usare quel metodo per trasformare un array creato in questo modo:

System.Windows.Point[] points = new Point[1000000];
Initialize(points);

Ecco, penso che il modo più veloce per farlo, poiché X e Y sono proprietà:

for (int i = 0; i < points.Length; i++)
{
    double x = points[i].X;
    double y = points[i].Y;
    TransformPoint(ref x, ref y);
    points[i].X = x;
    points[i].Y = y;
}

E sarà abbastanza buono! A meno che tu non abbia misurazioni che dimostrano il contrario, non c'è motivo di gettare una puzza. Ma credo che non sia tecnicamente garantito essere così veloce come questo:

internal struct MyPoint
{
    internal double X;
    internal double Y;
}

// ...

MyPoint[] points = new MyPoint[1000000];
Initialize(points);

// ...

for (int i = 0; i < points.Length; i++)
{
    TransformPoint(ref points[i].X, ref points[i].Y);
}

Effettuando alcune measurements solo, la versione con i campi richiede circa il 61% del tempo come versione con proprietà (.NET 4.6, Windows 7, x64, modalità di rilascio, nessun debugger collegato). Quanto più costoso diventa il metodo TransformPoint , tanto meno pronunciato diventa la differenza. Per ripetere tu stesso, corri con la prima riga commentata e con essa non commentata.

Anche se non ci sono benefici per le prestazioni di cui sopra, ci sono altri luoghi in cui la possibilità di utilizzare i parametri ref e out potrebbe essere utile, come quando si chiama la famiglia di metodi Interlocked o Volatile . Nota: nel caso in cui questo sia nuovo per te, Volatile è fondamentalmente un modo per ottenere lo stesso comportamento fornito dalla parola chiave volatile . Come tale, come volatile , non risolve magicamente tutti i problemi legati alla sicurezza del thread, come suggerisce il nome stesso.

Sicuramente non voglio sembrare come se stessi sostenendo che tu vai "oh, dovrei iniziare a esporre campi invece di proprietà". Il punto è che se hai bisogno di usare regolarmente questi membri in chiamate che prendono parametri "ref" o "out", specialmente su qualcosa che potrebbe essere un semplice tipo di valore che è improbabile che abbia mai bisogno di uno qualsiasi degli elementi a valore aggiunto delle proprietà, un argomento può essere fatto.




Da Wikipedia - Programmazione orientata agli oggetti :

La programmazione orientata agli oggetti (OOP) è un paradigma di programmazione basato sul concetto di "oggetti", che sono strutture di dati che contengono dati, sotto forma di campi , spesso noti come attributi; e codice, sotto forma di procedure, spesso conosciute come metodi . (enfasi aggiunta)

Le proprietà sono in realtà parte del comportamento di un oggetto, ma sono progettate per fornire ai consumatori dell'oggetto l'illusione / astrazione del lavoro con i dati dell'oggetto.




(Questo dovrebbe essere un commento, ma non posso pubblicare un commento, quindi scusami se non è appropriato come post).

Una volta ho lavorato in un luogo in cui lo studio consigliato consisteva nell'utilizzare i campi pubblici anziché le proprietà quando la def equivalente della proprietà avrebbe semplicemente dovuto accedere a un campo, come in:

get { return _afield; }
set { _afield = value; }

Il loro ragionamento era che il campo pubblico poteva essere convertito in una proprietà più tardi in futuro, se necessario. Mi è sembrato un po 'strano in quel momento. A giudicare da questi post, sembra che non molti qui sarebbero d'accordo. Cosa potevi dire per cercare di cambiare le cose?

Edit: Devo aggiungere che tutto il codice base in questo posto è stato compilato allo stesso tempo, quindi avrebbero potuto pensare che cambiare l'interfaccia pubblica delle classi (cambiando un campo pubblico in una proprietà) non fosse un problema.




Inoltre, le proprietà consentono di utilizzare la logica quando si impostano i valori.

Quindi puoi dire che vuoi solo impostare un valore su un campo intero, se il valore è maggiore di x, altrimenti lanciare un'eccezione.

Caratteristica davvero utile




Le proprietà incapsulano i campi, consentendo così di eseguire un'ulteriore elaborazione sul valore da impostare o recuperare. Generalmente è eccessivo usare le proprietà se non si sta facendo alcun pre o post-elaborazione sul valore del campo.




Sullo sfondo una proprietà è compilata in metodi. Quindi una proprietà Name è compilata in get_Name() e set_Name(string value) . Puoi vedere questo se studi il codice compilato. Quindi c'è un sovraccarico di prestazioni (molto) piccolo quando li si usa. Normalmente si utilizzerà sempre una proprietà se si espone un campo all'esterno e lo si utilizzerà spesso internamente se è necessario eseguire la convalida del valore.




Il mio progetto di un campo è che un campo deve essere modificato solo dal suo genitore, quindi dalla classe. Risultato la variabile diventa privata, quindi per essere in grado di dare il diritto di leggere le classi / metodi all'esterno passo il sistema di proprietà con solo Get. Il campo viene quindi recuperato dalla proprietà e di sola lettura! If you want to modify it you have to go through methods (for example the constructor) and I find that thanks to this way of making you secure, we have better control over our code because we "flange". One could very well always put everything in public so every possible case, the notion of variables / methods / classes etc ... in my opinion is just an aid to the development, maintenance of the code. For example, if a person resumes a code with public fields, he can do anything and therefore things "illogical" in relation to the objective, the logic of why the code was written. It's my point of view.

When i use a classic model private field / public readonly properties,for 10 privates fields i should write 10 publics properties! The code can be really big faster. I discover the private setter and now i only use public properties with a private setter. The setter create in background a private field.

That why my old classic programming style was:

public class MyClass
{
 private int _id;
 public int ID { get { return _id; } }
 public MyClass(int id)
 {
  _id = id;
 }
}

My new programming style:

public class MyClass
{
 public int ID { get; private set; }
 public MyClass(int id)
 {
  ID = id;
 }
}



quando hai una classe che è "Car". Le proprietà sono colore, forma ..

Dove i campi sono variabili definite nell'ambito di una classe.




Quando vuoi che la tua variabile privata (campo) sia accessibile all'oggetto della tua classe da altre classi devi creare proprietà per tali variabili.

per esempio se ho variabili chiamate "id" e "name" che sono private ma potrebbe esserci una situazione in cui questa variabile è necessaria per operazioni di lettura / scrittura al di fuori della classe. In questa situazione, la proprietà può aiutarmi a ottenere quella variabile in lettura / scrittura a seconda del risultato / set definito per la proprietà. Una proprietà può essere sia readonly / writeonly / readwrite.

ecco la demo

class Employee
{
    // Private Fields for Employee
    private int id;
    private string name;

    //Property for id variable/field
    public int EmployeeId
    {
       get
       {
          return id;
       }
       set
       {
          id = value;
       }
    }

    //Property for name variable/field
    public string EmployeeName
    {
       get
       {
          return name;
       }
       set
       {
          name = value;
       }
   }
}

class MyMain
{
    public static void Main(string [] args)
    {
       Employee aEmployee = new Employee();
       aEmployee.EmployeeId = 101;
       aEmployee.EmployeeName = "Sundaran S";
    }
}



Usando Properties, puoi lanciare un evento, quando il valore della proprietà viene modificato (aka. PropertyChangedEvent) o prima che il valore venga modificato per supportare l'annullamento.

Questo non è possibile con i campi (accesso diretto a).

public class Person {
 private string _name;

 public event EventHandler NameChanging;     
 public event EventHandler NameChanged;

 public string Name{
  get
  {
     return _name;
  }
  set
  {
     OnNameChanging();
     _name = value;
     OnNameChanged();
  }
 }

 private void OnNameChanging(){
   EventHandler localEvent = NameChanging;
   if (localEvent != null) {
     localEvent(this,EventArgs.Empty);
   }
 }

 private void OnNameChanged(){
   EventHandler localEvent = NameChanged;
   if (localEvent != null) {
     localEvent(this,EventArgs.Empty);
   }
 }
}



Le proprietà hanno il vantaggio principale di consentire di modificare il modo in cui si accede ai dati su un oggetto senza rompere la sua interfaccia pubblica. Ad esempio, se è necessario aggiungere una convalida aggiuntiva o modificare un campo memorizzato in un calcolo, è possibile farlo facilmente se inizialmente si espone il campo come proprietà. Se hai appena esposto un campo direttamente, dovresti modificare l'interfaccia pubblica della tua classe per aggiungere la nuova funzionalità. Quel cambiamento potrebbe rompere i client esistenti, richiedendo loro di essere ricompilati prima che potessero usare la nuova versione del tuo codice.

Se si scrive una libreria di classi progettata per un consumo ampio (come .NET Framework, che viene utilizzato da milioni di persone), ciò può rappresentare un problema. Tuttavia, se stai scrivendo una classe usata internamente in una piccola base di codice (diciamo <= 50 linee K), non è davvero un grosso problema, perché nessuno potrebbe essere influenzato negativamente dalle tue modifiche. In tal caso, si tratta solo di preferenze personali.




Tradizionalmente i campi privati ​​sono impostati tramite metodi getter e setter. Per motivi di meno codice è possibile utilizzare le proprietà per impostare i campi.







IMO, le proprietà sono solo le coppie di funzioni / metodi / interfacce "SetXXX ()" "GetXXX ()" utilizzate in precedenza, ma sono più concise ed eleganti.




Le proprietà sono un tipo speciale di membro della classe. Nelle proprietà utilizziamo un metodo Set o Get predefinito. Utilizzano gli accessor tramite i quali possiamo leggere, scrivere o modificare i valori dei campi privati.

Ad esempio, prendiamo una classe di nome Employee , con campi privati ​​per nome, età e Employee_Id. Non possiamo accedere a questi campi dall'esterno della classe, ma possiamo accedere a questi campi privati ​​attraverso le proprietà.

Perché usiamo le proprietà?

Rendere pubblico il campo classe ed esporlo è rischioso, in quanto non si avrà il controllo di ciò che viene assegnato e restituito.

Per comprenderlo chiaramente con un esempio, prendi una classe studentesca che ha ID, passmark, nome. Ora in questo esempio qualche problema con il campo pubblico

  • L'ID non dovrebbe essere -ve.
  • Il nome non può essere impostato su null
  • Il contrassegno deve essere letto solo
  • Se manca il nome dello studente, nessun nome deve essere restituito.

Per rimuovere questo problema Usiamo il metodo Get e set.

// A simple example
public class student
{
    public int ID;
    public int passmark;
    public string name;
}

public class Program
{
    public static void Main(string[] args)
    {
       student s1 = new student();
       s1.ID = -101; // here ID can't be -ve
       s1.Name = null ; // here Name can't be null
    }
}

Ora prendiamo un esempio di metodo get e set

public class student
{
    private int _ID;
    private int _passmark;
    private string_name ;
    // for id property
    public void SetID(int ID)
    {
        if(ID<=0)
        {
            throw new exception("student ID should be greater then 0");
        }
        this._ID = ID;
    }
    public int getID()
    {
        return_ID;
    }
}
public class programme
{
    public static void main()
    {
        student s1 = new student ();
        s1.SetID(101);
    }
    // Like this we also can use for Name property
    public void SetName(string Name)
    {
        if(string.IsNullOrEmpty(Name))
        {
            throw new exeception("name can not be null");
        }
        this._Name = Name;
    }
    public string GetName()
    {
        if( string.IsNullOrEmpty(This.Name))
        {
            return "No Name";
        }
        else
        {
            return this._name;
        }
    }
        // Like this we also can use for Passmark property
    public int Getpassmark()
    {
        return this._passmark;
    }
}



Dal momento che molti di loro hanno spiegato con pro e contro tecnici di Properties e Field , è il momento di entrare in esempi in tempo reale.

1. Proprietà consente di impostare il livello di accesso di sola lettura

Considera il caso di dataTable.Rows.Count e dataTable.Columns[i].Caption . Vengono dalla classe DataTable ed entrambi sono pubblici per noi. La differenza nel livello di accesso a loro è che non possiamo impostare valore su dataTable.Rows.Count ma possiamo leggere e scrivere su dataTable.Columns[i].Caption . È possibile attraverso il Field ? No!!! Questo può essere fatto solo con Properties .

public class DataTable
{
    public class Rows
    {       
       private string _count;        

       // This Count will be accessable to us but have used only "get" ie, readonly
       public int Count
       {
           get
           {
              return _count;
           }       
       }
    } 

    public class Columns
    {
        private string _caption;        

        // Used both "get" and "set" ie, readable and writable
        public string Caption
        {
           get
           {
              return _caption;
           }
           set
           {
              _caption = value;
           }
       }       
    } 
}

2. Proprietà in PropertyGrid

Potresti aver lavorato con Button in Visual Studio. Le sue proprietà sono mostrate in PropertyGrid come Text , Name ecc. Quando trasciniamo un pulsante e quando clicchiamo sulle proprietà, troverà automaticamente la classe Button e filtri Properties e mostreremo che in PropertyGrid (dove PropertyGrid non mostrerà Field anche se sono pubblici).

public class Button
{
    private string _text;        
    private string _name;
    private string _someProperty;

    public string Text
    {
        get
        {
           return _text;
        }
        set
        {
           _text = value;
        }
   } 

   public string Name
   {
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   } 

   [Browsable(false)]
   public string SomeProperty
   {
        get
        {
           return _someProperty;
        }
        set
        {
           _someProperty= value;
        }
   } 

In PropertyGrid , verranno mostrate le proprietà Name e Text , ma non SomeProperty . Perché??? Perché le proprietà possono accettare Attributes . Non viene visualizzato nel caso in cui [Browsable(false)] sia false.

3. Può eseguire istruzioni all'interno di Proprietà

public class Rows
{       
    private string _count;        


    public int Count
    {
        get
        {
           return CalculateNoOfRows();
        }  
    } 

    public int CalculateNoOfRows()
    {
         // Calculation here and finally set the value to _count
         return _count;
    }
}

4. Solo le proprietà possono essere utilizzate in Binding Source

Binding Source ci aiuta a ridurre il numero di righe di codice. Fields non sono accettati da BindingSource . Dovremmo usare le Properties per quello.

5. Modalità di debug

Considera che stiamo usando Field per mantenere un valore. A un certo punto dobbiamo eseguire il debug e verificare dove il valore sta diventando nullo per quel campo. Sarà difficile da fare dove il numero di righe di codice è più di 1000. In tali situazioni possiamo usare Property e possiamo impostare la modalità di debug all'interno di Property .

   public string Name
   {
        // Can set debug mode inside get or set
        get
        {
           return _name;
        }
        set
        {
           _name = value;
        }
   }



Ti darò un paio di esempi di utilizzo di proprietà che potrebbero far girare gli ingranaggi:

  • Inizializzazione pigra : se si dispone di una proprietà di un oggetto che è costoso da caricare, ma non si accede a tutto ciò nelle normali esecuzioni del codice, è possibile ritardarne il caricamento tramite la proprietà. In questo modo, è solo seduto lì, ma la prima volta che un altro modulo tenta di chiamare quella proprietà, controlla se il campo sottostante è nullo - se lo è, va avanti e lo carica, sconosciuto al modulo chiamante. Ciò può velocizzare notevolmente l'inizializzazione dell'oggetto.
  • Tracciamento sporco: che in realtà ho imparato dalla mia stessa domanda qui su . Quando ho molti oggetti che i valori potrebbero essere cambiati durante una corsa, posso usare la proprietà per tenere traccia se devono essere salvati nel database o meno. Se non è stata modificata una singola proprietà di un oggetto, il flag IsDirty non verrà attivato, e quindi la funzionalità di salvataggio salterà su di esso al momento di decidere cosa è necessario tornare al database.



The vast majority of cases it's going to be a property name that you access as opposed to a variable name ( field ) The reason for that is it's considered good practice in .NET and in C# in particular to protect every piece of data within a class, whether it's an instance variable or a static variable (class variable) because it's associated with a class.

Protect all of those variables with corresponding properties which allow you to define, set and get accessors and do things like validation when you're manipulating those pieces of data.

But in other cases like Math class (System namespace), there are a couple of static properties that are built into the class. one of which is the math constant PI

per esempio. Math.PI

and because PI is a piece of data that is well-defined, we don't need to have multiple copies of PI, it always going to be the same value. So static variables are sometimes used to share data amongst object of a class, but the are also commonly used for constant information where you only need one copy of a piece of data.




Una differenza importante è che le interfacce possono avere proprietà ma non campi. Questo, per me, sottolinea che le proprietà dovrebbero essere utilizzate per definire l'interfaccia pubblica di una classe mentre i campi sono pensati per essere utilizzati nei meccanismi interni privati ​​di una classe. Di regola raramente creo campi pubblici e, analogamente, raramente creo proprietà non pubbliche.