Quando usare [Pure] su un costruttore?

15

Sto imparando sui contratti di codice in .NET, e sto cercando di capire l'idea dei puri costruttori. Gli stati della documentazione contratti di codice :

All methods that are called within a contract must be pure; that is, they must not update any preexisting state. A pure method is allowed to modify objects that have been created after entry into the pure method.

E PureAttribute stati della documentazione:

Indicates that a type or method is pure, that is, it does not make any visible state changes.

Capisco queste affermazioni quando si tratta di metodi, ma per quanto riguarda i costruttori? Supponi di avere una classe come questa:

public class Foo
{
    public int Value { get; set; }

    public Foo(int value) {
        this.Value = value;
    }
}

Questo costruttore ovviamente influisce sullo stato del nuovo oggetto Foo , ma non ha altri effetti collaterali (ad esempio non manipola nessuno dei parametri o chiama metodi non puri). È un candidato per [Pure] o no? Qual è il significato del posizionamento di un attributo [Pure] su un costruttore e quando dovrei farlo nel mio codice?

    
posta p.s.w.g 01.07.2014 - 18:20
fonte

2 risposte

11

Decora un metodo con [Pure] :

  • Se il metodo non ha effetti collaterali. Ad esempio, se il metodo accede a un database e lo modifica o il suo risultato dipende dal database, non è puro.

  • E se prevedi di usarlo nei contratti di codice. Ad esempio, se il metodo è puro , ma non hai intenzione di usarlo nei contratti di codice, aggiungere [Pure] non avrebbe alcun vantaggio e non renderà il tuo codice più veloce.

Per quanto riguarda i costruttori, sembra che assunto sia puro in .NET e non necessiti di un attributo esplicito. Ho esaminato diversi costruttori in origine .NET Framework, come DateTime , e non hanno% attributo[Pure].

Suppongo che ciò avvenga per diversi motivi:

  • Potrebbe essere troppo poco pratico dover scrivere un costruttore senza parametri con l'attributo [Pure] solo per poter usare la classe / struct in un contratto.

  • Alcuni, come String , non hanno costruttori espliciti.

  • I costruttori ricevono un trattamento speciale anche al di fuori dei contratti di codice; ad esempio, non è previsto che vengano generate eccezioni al loro interno .

  • [Pure] è solo una convenzione che è qui per semplificarti la vita, ma non esiste un controllo statico reale per garantire che il metodo decorato con questo attributo sia puro. void DestroyDatabase() può essere decorato come puro e i contratti di codice non noteranno nulla di sbagliato.

    Currently there is no component of Code Contracts which checks if methods declared pure are pure indeed. Thus if a programmer decorated a method with [Pure], it’s just believed.

    From Code Contracts #5: Method purity

  • .NET Framework stesso contiene costruttori che non sono puri. Ad esempio, List<T>(IEnumerable<T> collection) è in realtà impuro se esegui il looping della raccolta ha effetti collaterali.

  • I contratti devono essere semplici. Posso facilmente immaginare un contratto come Contract.Requires(!string.IsNullOrEmpty(name)) , quindi ci sono buone ragioni per dichiarare lo stat% string.IsNullOrEmpty puro.

    D'altra parte, se hai bisogno di un StringBuilder per costruire la stringa, controllerai qualcosa chiamando un metodo di istanza della tua classe business, probabilmente stai utilizzando in modo improprio i contratti. Questo è anche il motivo per cui StringBuilder.ToString non è contrassegnato come puro, anche se potrebbe essere (è?)

risposta data 01.07.2014 - 18:52
fonte
1

L'oggetto non può essere utilizzato fino a quando non viene costruito in questo caso. Quindi il costruttore è puro. Se il costruttore ha chiamato un altro codice o ha invocato un delegato e l'altro codice ha modificato la proprietà mutabile, non sarebbe puro. Per essere più sicuro, è meglio rendere la proprietà immutabile.

    
risposta data 01.07.2014 - 18:26
fonte

Leggi altre domande sui tag