C #: vantaggio di dichiarare esplicitamente & # 8220; non sicuro & # 8221; / opzione del compilatore

StackOverflow https://stackoverflow.com/questions/607159

Domanda

Comprendo i puntatori e la rara necessità di usarli nel codice C #. La mia domanda è: qual è il ragionamento alla base del dover dichiarare esplicitamente "non sicuro" in un blocco di codice. Inoltre, perché un'opzione del compilatore deve essere modificata per consentire " non sicuro " codice?

Conclusione: ciò che nel CLR (o le specifiche del linguaggio) lo rende così non possiamo semplicemente usare i puntatori ogni volta che vogliamo (proprio come C e C ++) senza dover digitare " unsafe " e modificare l'opzione del compilatore?

Per chiarimenti: so cosa " non sicuro " e "sicuro" il codice è. È solo una domanda sul perché dobbiamo fare tutto il lavoro extra (ok, non QUANTO extra) solo per poter usare queste funzionalità.

È stato utile?

Soluzione

C'è un'intervista con il creatore di C # Anders Hejlsberg che tocca l'argomento qui . Fondamentalmente, esattamente quello che ha detto @Marc Gravell: prima la sicurezza dei caratteri, non la sicurezza con una dichiarazione esplicita.

Quindi, per rispondere alla tua domanda: nulla nel CLR lo impedisce; è un linguaggio linguistico progettato per permetterti di lavorare con i guanti di sicurezza quando hai a che fare con i tipi. Se vuoi toglierti i guanti, è la tua scelta, ma devi fare la scelta attiva per toglierli.

Modifica

  

Per chiarimenti: so cosa   & Quot; sicuri " e "sicuro" il codice è. È appena   una domanda sul perché dobbiamo fare tutto   lavoro extra (ok, non così tanto extra)   solo per poter usare queste funzionalità.

Come menzionato nell'intervista che ho collegato, è stata una decisione esplicita di progettazione. C # è essenzialmente un'evoluzione di Java e in Java, non hai affatto puntatori. Ma i progettisti volevano consentire i puntatori; tuttavia, poiché C # in genere portava sviluppatori Java, ritenevano che sarebbe stato meglio se il comportamento predefinito fosse simile a Java, cioè senza puntatori, pur consentendo comunque l'uso di puntatori con una dichiarazione esplicita.

Quindi il " lavoro extra " è intenzionale a costringerti a pensare a quello che stai facendo prima di farlo. Essendo esplicito, ti obbliga almeno a considerare: " Perché lo sto facendo? Davvero ho bisogno di un puntatore quando sarà sufficiente un tipo di riferimento? & Quot;

Altri suggerimenti

Si tratta in gran parte di essere verificabili. Dichiarando non sicuro , i guanti sono spenti: il sistema non può più garantire che il tuo codice non funzioni. Nella maggior parte dei casi è altamente desiderabile rimanere nella zona sicura.

Questo diventa più evidente con un trust parziale (componenti aggiuntivi, ecc.), ma è comunque prezioso nel codice normale.

In realtà il CLR non richiede assolutamente alcuna opzione / parola chiave non sicura. In effetti, C ++ / CLI (il linguaggio C ++ che gira sotto il CLR) non ha tale / unsafe switch e i puntatori possono essere usati liberamente sul CLR.

Quindi riformulerei la tua domanda come " Perché C # richiede l'uso di / non sicuro prima di poter usare i puntatori? " E la risposta a questa domanda è come indicato in altre risposte fornite qui: per aiutare l'utente a prendere una decisione consapevole di perdere la capacità di correre in qualcosa di meno della modalità Full Trust sul CLR. C ++ richiede praticamente sempre la fiducia completa sul CLR e C # può ogni volta che chiami codice che richiede la fiducia completa o ogni volta che usi i puntatori.

Quando si utilizza un blocco non sicuro, ha l'effetto di rendere non verificabile il codice. Ciò richiede l'esecuzione di determinate autorizzazioni e potresti non volerlo autorizzare nel tuo output (specialmente se ti trovi in ??un ambiente di origine condiviso), quindi c'è un interruttore nel compilatore per impedirlo.

Pensaci dal punto di vista opposto: poiché non è contrassegnato come non sicuro, puoi dedurre che la maggior parte del codice è "sicuro". per impostazione predefinita. Quindi cosa significa essere "sicuri"? Per il codice .Net, questo include (ma non può essere limitato a):

  • Il garbage collector può fare affari come al solito.
  • I riferimenti a un tipo specifico faranno riferimenti a oggetti di quel tipo (o null).
  • Il codice è garantito per soddisfare i requisiti di affidabilità / sicurezza .Net.
  • È dimostrato matematicamente che il codice non tocca direttamente la memoria all'esterno del proprio AppDomain. Può sembrare banale, ma immagina se hai più AppDomain nella stessa applicazione. Il programmatore può considerarli con sicurezza come logicamente separati.

Ogni volta che usi i puntatori hai la possibilità di rompere una di quelle garanzie. Pertanto contrassegnare il codice come non sicuro rinuncia a tali protezioni.

In breve, .NET vuole che tu dichiari le tue intenzioni.

Certo, il compilatore potrebbe dedurre la necessità di "non sicuro" bandiera. Ma i progettisti vogliono che sia una decisione deliberata.

Per me è simile a una serie di requisiti sintattici in C #:

  • nessuna custodia senza interruzione
  • nessun livello di accesso "sezioni" (come il marcatore " public: " in C ++)
  • nessun campo di classe che utilizza " var "

Lo schema è che non dovresti spostare o cambiare una cosa e influenzarne inavvertitamente un'altra. Entro limiti ragionevoli, vogliono impedirti di "spararti al piede". & Quot;

Molte ottime risposte informative qui & # 8212; forse questo va di più alla tua domanda.

In modo che sia immediatamente ovvio quale codice non verrà eseguito nei servizi Web senza autorizzazioni elevate, ecc.

Nutrire buone abitudini e amp; sicurezza. Ogni volta che si utilizza un blocco non sicuro in un assembly, verrà richiesta un'autorizzazione NativeCode dallo stack. Questo potrebbe ovviamente essere fatto implicitamente, ma non potremmo anche rimuovere completamente la parola chiave privata? Penso che sia bene costringere gli sviluppatori a richiedere specificamente un codice non sicuro prima di poterlo utilizzare.

La differenza più significativa tra il codice sicuro e quello non sicuro è che il codice non sicuro non è raggiungibile dal garbage collector di .net. GC automatico è una parte enorme del vernacolo di .net e, quando vai oltre i suoi confini, cambi molto di ciò che si può presumere riguardo al tuo codice.

I puntatori in particolare consentono la creazione di oggetti sull'heap senza riferimenti GC. Ciò porta a un'altra eccellente ragione per richiedere che il codice sia contrassegnato come "non sicuro". Rende facile restringere la provenienza di una perdita di memoria quando ti rendi conto di averne una.

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