Domanda

Con il nuovo approccio di avere get / set all'interno dell'attributo della classe in questo modo:

public string FirstName {
        get; set;
    }

Perché semplicemente non semplicemente rendere l'attributo FirstName pubblico senza accessor?

È stato utile?

Soluzione

Due dei maggiori problemi con l'accesso diretto alla variabile all'interno della classe (campo / attributo) sono:

1) Non è possibile eseguire facilmente il databind rispetto ai campi.

2) Se esponi i campi pubblici dalle tue classi non puoi successivamente modificarli in proprietà (ad esempio: per aggiungere la logica di validazione ai setter)

Altri suggerimenti

Perché, in futuro, se si modifica l'implementazione, il codice che utilizza l'interfaccia corrente non si interromperà.

Ad esempio, si implementa una classe semplice con un campo pubblico e si inizia a utilizzare la classe in alcuni moduli esterni. Un mese dopo scopri che devi implementare il caricamento lento in quella classe. Dovresti quindi trasformare il campo in una proprietà. Dal punto di vista del modulo esterno, potrebbe sembrare la stessa sintassi, ma non lo è. Una proprietà è un insieme di funzioni, mentre un campo è un offset in un'istanza di classe.

Utilizzando una proprietà, si riduce efficacemente il rischio che l'interfaccia cambierà.

Ciò dipende principalmente dal fatto che è diventata una convenzione di codifica comune. Se lo desideri, semplifica l'aggiunta di un codice di elaborazione personalizzato. Ma hai ragione, tecnicamente non è necessario. Tuttavia, se aggiungi un'elaborazione personalizzata in un secondo momento, ciò ti aiuterà a non interrompere l'interfaccia.

Questo stile di notazione è più utile quando si mescola l'accessibilità per il getter e il setter. Ad esempio, puoi scrivere:

public int Foo { get; private set; }

Potresti anche mettere un setter interno o persino rendere il getter privato e il setter pubblico.

Questa notazione evita la necessità di scrivere esplicitamente una variabile privata solo per gestire il classico problema del valore scrivibile internamente / leggibile esternamente.

La chiave è che il compilatore traduce la proprietà 'under the hood' in una coppia di funzioni, e quando hai un codice che sembra che stia usando la proprietà, in realtà chiama le funzioni quando viene compilato in IL.

Quindi diciamo che lo costruisci come un campo e hai il codice in un assembly separato che usa questo campo. Se in seguito l'implementazione cambia e si decide di renderlo una proprietà per nascondere le modifiche al resto del codice, è comunque necessario ricompilare e ridistribuire l'altro assembly. Se è una proprietà fin dall'inizio, le cose funzioneranno e basta.

Penso che l'interrogante stia chiedendo perché non fare quanto segue ...

public string FirstName { }

Perché preoccuparsi degli accessori quando potresti accorciarli a quanto sopra. Penso che la risposta sia che richiedere agli accessor rende ovvio alla persona che legge il codice che è un get / set standard. Senza di loro puoi vedere sopra, è difficile individuare che questo viene implementato automaticamente.

Quando ricevi un bug e devi scoprire quali metodi stanno modificando i tuoi campi e quando, ti preoccuperai molto di più. Mettere gli accesori di proprietà leggeri in primo piano consente di risparmiare una quantità fenomenale di mal di cuore in caso di insorgenza di un bug che coinvolge il campo avvolto. Sono stato in quella situazione un paio di volte e non è piacevole, soprattutto quando si rivela essere correlato al rientro.

Fare questo lavoro in anticipo e attaccare un punto di interruzione su un accessorio è molto più facile delle alternative.

Per il 99% dei casi, esporre un campo pubblico va bene.

Il consiglio comune è di usare i campi: " Se esponi i campi pubblici dalle tue classi, non puoi successivamente cambiarli in proprietà " ;. So che tutti vogliamo che il nostro codice sia a prova di futuro, ma ci sono alcuni problemi con questo pensiero:

  • Probabilmente i consumatori della tua classe possono ricompilarsi quando cambi l'interfaccia.

  • Il 99% dei membri dei dati non dovrà mai diventare proprietà non banali. È generalità speculativa . Stai scrivendo molto codice che probabilmente non sarà mai utile.

  • Se è necessaria la compatibilità binaria tra le versioni, probabilmente rendere membri dei dati nelle proprietà non è sufficiente. Per lo meno, dovresti solo esporre interfacess e nascondere tutti i costruttori ed esporre fabbriche (vedi codice sotto).


public class MyClass : IMyClass
{
    public static IMyClass New(...)
    {
        return new MyClass(...);
    }
}

È un problema difficile, provare a creare codice che funzionerà in un futuro incerto. Davvero difficile.

Qualcuno ha un esempio di un tempo in cui l'utilizzo di proprietà banali ha salvato la loro pancetta ?

Conserva l'incapsulamento dell'oggetto e riduce il codice per renderlo più semplice da leggere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top