Gli accessi sono più che campi. Altri hanno già fatto notare alcune importanti differenze e ne aggiungerò un'altra.
Le proprietà partecipano alle classi di interfaccia. Ad esempio:
interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
Questa interfaccia può essere soddisfatta in diversi modi. Per esempio:
class Person: IPerson
{
private string _name;
public string FirstName
{
get
{
return _name ?? string.Empty;
}
set
{
if (value == null)
throw new System.ArgumentNullException("value");
_name = value;
}
}
...
}
In questa implementazione stiamo proteggendo sia la classe Person
di entrare in uno stato non valido, così come il chiamante di ottenere nulla fuori dalla proprietà non assegnato.
Ma potremmo spingere ulteriormente il design. Ad esempio, l'interfaccia potrebbe non occuparsi del setter.E 'del tutto legittimo dire che i consumatori di IPerson
interfaccia sono interessati solo a ottenere la proprietà, non in impostazione:
interface IPerson
{
string FirstName { get; }
string LastName { get; }
}
Precedente attuazione dei soddisfa classe Person
questa interfaccia. Il fatto che consenta al chiamante di impostare anche le proprietà è privo di significato dal punto di vista dei consumatori (che consumano IPerson
). Ulteriori funzionalità della realizzazione concreta viene preso in considerazione, ad esempio, costruttore:
class PersonBuilder: IPersonBuilder
{
IPerson BuildPerson(IContext context)
{
Person person = new Person();
person.FirstName = context.GetFirstName();
person.LastName = context.GetLastName();
return person;
}
}
...
void Consumer(IPersonBuilder builder, IContext context)
{
IPerson person = builder.BuildPerson(context);
Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
In questo codice, i consumatori non conosce setter di proprietà - non è affar suo saperlo. Il consumatore ha bisogno solo di getter e riceve i getter dall'interfaccia, cioè dal contratto.
Un'altra tutto valido attuazione IPerson
sarebbe una classe persona immutabile ed una corrispondente fabbrica persona:
class Person: IPerson
{
public Person(string firstName, string lastName)
{
if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName))
throw new System.ArgumentException();
this.FirstName = firstName;
this.LastName = lastName;
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
}
...
class PersonFactory: IPersonFactory
{
public IPerson CreatePerson(string firstName, string lastName)
{
return new Person(firstName, lastName);
}
}
...
void Consumer(IPersonFactory factory)
{
IPerson person = factory.CreatePerson("John", "Doe");
Console.WriteLine("{0} {1}", person.FirstName, person.LastName);
}
In questo codice di esempio consumatore una volta non è a conoscenza di riempire le proprietà. Il consumatore tratta solo i getter e l'implementazione concreta (e la logica di business dietro di esso, come testare se il nome è vuoto) è lasciata alle classi specializzate - costruttori e fabbriche. Tutte queste operazioni sono assolutamente impossibili con i campi.
possibile duplicato di [getter e setter implementati automaticamente rispetto ai campi pubblici] (http://stackoverflow.com/questions/111461/auto-implemented-getters-and-setters-vs-public-fields) – nawfal