CA1810: Inizializzare i campi statici del tipo di riferimento inline
TypeName |
InitializeReferenceTypeStaticFieldsInline |
CheckId |
CA1810 |
Category |
Microsoft.Performance |
Breaking Change |
Non sostanziale |
Causa
Un tipo di riferimento dichiara un costruttore statico esplicito.
Descrizione della regola
Quando un tipo dichiara un costruttore statico esplicito, tramite il compilatore JIT (Just-In-Time) viene aggiunto un controllo a ogni metodo statico del tipo e a ogni costruttore di istanza del tipo per assicurare che il costruttore statico sia stato precedentemente chiamato.L'inizializzazione statica viene attivata quando si accede a un membro statico o quando viene creata un'istanza del tipo.L'inizializzazione statica tuttavia non viene attivata se si dichiara una variabile del tipo ma non la si utilizza, una condizione importante se l'inizializzazione modifica lo stato globale.
Quando tutti i dati statici vengono inizializzati inline e non viene dichiarato un costruttore statico esplicito, i compilatori MSIL (Microsoft Intermediate Language) aggiungono alla definizione di tipo MSIL il flag beforefieldinit e un costruttore statico implicito che inizializza i dati statici.Quando il compilatore JIT rileva il flag beforefieldinit, nella maggior parte dei casi i controlli del costruttore statico non vengono aggiunti.L'inizializzazione statica viene sicuramente eseguita prima che si acceda a qualsiasi campo statico, ma non prima che venga richiamato un metodo statico o un costruttore di istanza.Notare che l'inizializzazione statica può essere eseguita in qualsiasi momento dopo la dichiarazione di una variabile del tipo.
I controlli dei costruttori statici possono ridurre le prestazioni.Un costruttore statico viene spesso utilizzato solo per inizializzare campi statici, nel qual caso è sufficiente assicurare che l'inizializzazione statica venga eseguita prima del primo accesso a un campo statico.Il comportamento di beforefieldinit è appropriato per questi tipi e per la maggior parte degli altri,ma non lo è solo quando l'inizializzazione statica influisce sullo stato globale e viene soddisfatta una delle seguenti condizioni:
L'effetto sullo stato globale è dispendioso e non è necessario se il tipo non è utilizzato.
È possibile accedere agli effetti sullo stato globale senza accedere ad alcun campo statico del tipo.
Come correggere le violazioni
Per correggere una violazione di questa regola, inizializzare tutti i dati statici quando vengono dichiarati e rimuovere il costruttore statico.
Esclusione di avvisi
L'esclusione di un avviso da questa regola è sicura se le prestazioni non sono importanti o se le modifiche allo stato globale causate dall'inizializzazione statica sono dispendiose o devono necessariamente essere eseguite prima che venga chiamato un metodo statico del tipo o venga creata un'istanza del tipo.
Esempio
Nell'esempio riportato di seguito vengono illustrati il tipo StaticConstructor, che viola la regola, e il tipo NoStaticConstructor, che sostituisce il costruttore statico con l'inizializzazione inline per soddisfare la regola.
Imports System
Imports System.Resources
Namespace PerformanceLibrary
Public Class StaticConstructor
Shared someInteger As Integer
Shared resourceString As String
Shared Sub New()
someInteger = 3
Dim stringManager As New ResourceManager("strings", _
System.Reflection.Assembly.GetExecutingAssembly())
resourceString = stringManager.GetString("string")
End Sub
End Class
Public Class NoStaticConstructor
Shared someInteger As Integer = 3
Shared resourceString As String = InitializeResourceString()
Shared Private Function InitializeResourceString()
Dim stringManager As New ResourceManager("strings", _
System.Reflection.Assembly.GetExecutingAssembly())
Return stringManager.GetString("string")
End Function
End Class
End Namespace
using System;
using System.Reflection;
using System.Resources;
namespace PerformanceLibrary
{
public class StaticConstructor
{
static int someInteger;
static string resourceString;
static StaticConstructor()
{
someInteger = 3;
ResourceManager stringManager =
new ResourceManager("strings", Assembly.GetExecutingAssembly());
resourceString = stringManager.GetString("string");
}
}
public class NoStaticConstructor
{
static int someInteger = 3;
static string resourceString = InitializeResourceString();
static string InitializeResourceString()
{
ResourceManager stringManager =
new ResourceManager("strings", Assembly.GetExecutingAssembly());
return stringManager.GetString("string");
}
}
}
Si noti l'aggiunta del flag beforefieldinit alla definizione MSIL della classe NoStaticConstructor.
Regole correlate
CA2207: Inizializzare i campi statici dei tipi di valore inline