Esiste un'alternativa migliore rispetto all'abusare del modello IDisposable?

4

Considera il seguente codice (sanzionato da Microsoft):

<% using (Html.Form<HomeController>(action=>action.Index())) { %>

    <input type="text" id="search" />

    <input type="button" value="Submit" />

<% } %>

L'istruzione using non ha uno scopo qui: per aggiungere un tag </form> alla fine dell'HTML generato.

Questo mi sembra sporco, per quello che spero siano ovvi motivi:

  1. Non è la ragion d'essere di using .
  2. Causa deliberatamente effetti collaterali.
  3. Non è intuitivo che Html.Form implementerebbe IDisposable .
  4. L'istruzione using non è effettivamente richiesta, ma Html.Form si interromperà senza di essa (a meno che tu non emetta </form> te stesso, che manchi l'intero punto).

Questo è non l'unico abuso che le persone hanno accumulato sul pattern using .

La domanda è: esiste un'alternativa valida che fornisca gli stessi vantaggi stilistici / di leggibilità di using , senza farti venire voglia di fare una doccia dopo?

    
posta Robert Harvey 26.08.2014 - 19:14
fonte

1 risposta

4

No, non in .NET al momento.

using (di design) è l'unica cosa che è garantita per avere quel tipo di esecuzione deterministica in due parti con cui puoi effettivamente lavorare. ( lock fa anche questo, ma non espone nulla a cui puoi connetterti - e sarebbe più sporco)

Le soluzioni AoP possono forse aiutare, ma non ho visto nessuna che funzioni bene a livello di sotto-funzione, figuriamoci in template html.

C'è la possibilità di passare un delegato anonimo in una funzione (che poi esegue il lambda e elimina la risorsa), ma è brutto:

Using.Transaction(new Resource(), ()=>{
  Foo();
  Bar();
});

E ha alcune limitazioni:

  • Il compilatore non imporrà che la risorsa sia una risorsa precedentemente non dichiarata come using blocks do.
  • Non puoi uscire dal lambda in modo non convenzionale come se fosse possibile utilizzare un blocco (tramite return , break , continue , yield , goto )
    • (anche se il caso di rendimento è un bug di linguaggio noto e gli altri casi di non ritorno sono molto spiacevoli)
  • Non puoi accedere a ref / out param da lambda.
  • Non puoi utilizzare il codice unsafe nel lambda.
  • Non puoi " catena " utilizzare correttamente i blocchi.

La maggior parte di questi può essere aggirata usando metodi denominati piuttosto che anonimi, ma ciò porta ai propri problemi.

    
risposta data 26.08.2014 - 19:30
fonte

Leggi altre domande sui tag