safe (Riferimenti per C#)

La safe parola chiave contestuale contrassegna una dichiarazione come non richiede un unsafe contesto nel relativo sito di utilizzo nel modello di sicurezza della memoria aggiornato. Il safe modificatore è la controparte di unsafe. Un contesto non sicuro non è necessario per i chiamanti di una safe dichiarazione, mentre unsafe propaga l'obbligo di controllare la sicurezza al chiamante.

L'uso della safe parola chiave stessa richiede l'opzione del AllowUnsafeBlocks compilatore (-unsafe), anche se i chiamanti non necessitano di un unsafe contesto. Le dichiarazioni comuni sono sicure per impostazione predefinita, quindi omettere safe dove non è necessario evitare inutilmente la compilazione non sicura.

Importante

La safe parola chiave fa parte del modello aggiornato di sicurezza della memoria, una funzionalità di anteprima in C# 15 e .NET 11. Impostare LangVersion su preview per abilitare la sintassi. Per applicare anche le regole aggiornate, incluse le scelte esplicite safe o unsafe e gli obblighi del chiamante non sicuro, abilitare la funzionalità del updated-memory-safety-rules compilatore. Per informazioni dettagliate sull'attivazione, vedere Abilitare le regole di sicurezza della memoria aggiornate. Per la progettazione completa, vedere la specifica della funzionalità di sicurezza della memoria.

Dichiarazioni consentite e obbligatorie

È possibile applicare safe alle dichiarazioni che consentono un modificatore non sicuro, inclusi metodi, costruttori, proprietà e campi. Per le dichiarazioni normali, il modificatore può rendere esplicito il contratto previsto, incluso nel codice generato dall'origine. Non è limitato ai membri e ai extern campi di layout.

Alcune dichiarazioni richiedono una scelta esplicita di safe o unsafe quando le regole aggiornate sono abilitate. Le sezioni seguenti descrivono extern i membri e i campi di layout espliciti o estesi.

A differenza di unsafe, safe non stabilisce un contesto lessicale. Non esegue operazioni non sicure in un corpo membro sicuro o annulla un contesto non sicuro. Non è possibile combinare i safe modificatori e unsafe nella stessa dichiarazione. In questo modo viene generato CS9388.

Nei compilatori più recenti, safe le dichiarazioni richiedono AllowUnsafeBlocksanche , anche se i chiamanti non necessitano di un contesto non sicuro. Impostare <AllowUnsafeBlocks>true</AllowUnsafeBlocks> nel file di progetto per risolvere CS9401. Questo controllo del modificatore è indipendente dal consenso esplicito aggiornato per l'imposizione delle regole. Roslyn lo documenta come introdotto in Visual Studio 2026 versione 18.13, dopo .NET 11.0.100; il compilatore .NET 11 RC2 non applica questo requisito per safe. Per il limite del compilatore e la distinzione da CS0227 in blocchi non sicuri, vedere Requisiti del contesto unsafe.

Membri extern

Un extern membro chiama nel codice nativo, in modo che il compilatore non possa classificarne la sicurezza. Nel modello aggiornato contrassegnare ogni extern dichiarazione, incluso un LibraryImport metodo parziale, safe o unsafe:

// Syntax requires LangVersion preview; enforcement requires the updated-memory-safety-rules compiler feature.
[LibraryImport("libc")]
internal static safe partial int getpid();

[LibraryImport("libc", StringMarshalling = StringMarshalling.Utf8)]
internal static unsafe partial nint strlen(byte* str);

getpid non accetta parametri e restituisce una primitiva, quindi l'autore attesta che la chiamata è sicura e i chiamanti lo usano senza un unsafe contesto. strlen accetta un puntatore non elaborato che il codice nativo dereferenzia, quindi la dichiarazione è unsafe e propaga l'obbligo ai chiamanti. Con le regole aggiornate abilitate, l'omissione di entrambi i modificatori è un errore.

Campi di layout espliciti o estesi

In un tipo con [StructLayout(LayoutKind.Explicit)] o [ExtendedLayout], il compilatore non può classificare autonomamente la sicurezza di ogni campo dell'istanza. Ogni campo safe o unsafe:

// Syntax requires LangVersion preview; enforcement requires the updated-memory-safety-rules compiler feature.
[StructLayout(LayoutKind.Explicit)]
internal struct Union
{
    [FieldOffset(0)]
    internal safe int AsInt;

    [FieldOffset(0)]
    internal safe float AsFloat;
}

Un campo che contiene un puntatore nativo o il cui tipo contiene in caso contrario un oggetto invariante che il sistema di tipi non può esprimere, è unsafe. Campo il cui tipo è descritto completamente dal sistema di tipi è safe. La stessa regola si applica ai campi di layout esplicito e ai campi di layout esteso. Come per extern i membri, l'omissione di entrambi i modificatori è un errore quando le regole aggiornate sono abilitate.

Applicare gli stessi modificatori ai campi dell'istanza in tipi con diverso da zero StructLayoutAttribute.Pack o StructLayoutAttribute.Size, inclusi layout sequenziale e automatico. Ad esempio, un tipo di layout sequenziale con Pack = 1 richiede la stessa scelta esplicita. I valori non specificati o zero non attivano autonomamente la regola aggiuntiva. I campi statici e costanti sono esenti. Per i campi di backup sintetizzati, inserire il modificatore nella proprietà o nell'evento proprietario.

Per il messaggio CS9392 e le correzioni per altre risorse di archiviazione sintetizzate, vedere Sicurezza del layout dei campi.

Specificazione del linguaggio C#

Per altre informazioni, vedere Codice unsafe nella specifica del linguaggio C#. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.

Per la progettazione del modello di sicurezza della memoria aggiornato, vedere la specifica della funzionalità di sicurezza della memoria.

Vedere anche