CA1810: inicializar campos estáticos de tipo de referência embutido
TypeName |
InitializeReferenceTypeStaticFieldsInline |
CheckId |
CA1810 |
Categoria |
Microsoft.Performance |
Alteração Significativa |
Sem quebra |
Causa
Um tipo de referência declara um construtor estático explícito.
Descrição da Regra
Quando um tipo declara um construtor estático explícito, o compilador de (JIT) just-in-time adiciona uma verificação a cada construtor de método estático e da instância do tipo para garantir que o construtor estático esteve chamado anteriormente.A inicialização estático é disparada quando qualquer membro estático é acessado ou quando uma instância do tipo é criada.No entanto, a inicialização estático não será disparada se você a seguir declara uma variável do tipo mas não o usa o, que pode ser importante se a inicialização altera o estado global.
Quando todos os dados estáticos forem embutidos inicializado e um construtor estático explícito não esteja declarado, os compiladores de linguagem intermediária da Microsoft (MSIL) adiciona o sinalizador de beforefieldinit e um construtor estático implícito, que inicializa os dados estáticos, definição de tipo de MSIL.Quando o compilador JIT encontrar o sinalizador de beforefieldinit , as verificações estáticos de construtor não serão adicionadas na maioria das vezes.A inicialização estático é garantida para ocorrer em qualquer dia antes que todos os campos estáticos são acessadas mas não antes que um construtor de método estático ou da instância seja invocado.Observe que a inicialização estático pode ocorrer a qualquer momento depois que uma variável de tipo é declarado.
As verificações estáticos de construtor podem diminuir o desempenho.Um construtor estático é frequentemente usado para inicializar somente campos estáticos nesse caso, você só deve assegurar que a inicialização estático ocorre antes do primeiro acesso de um campo estático.O comportamento de beforefieldinit é adequado para esses e a maioria dos outros tipos.Inadequado é somente quando a inicialização estático afeta o estado global e um dos seguintes for verdadeiro:
O efeito no estado global é caro e não será necessário se o tipo não é usado.
Os efeitos globais do estado podem ser acessados sem acessar os campos estáticos do tipo.
Como Corrigir Violações
Para corrigir uma violação desta regra, inicializar todos os dados estáticos quando é declarada e remover o construtor estático.
Quando Suprimir Alertas
É seguro suprimir um aviso desta regra não se o desempenho for uma preocupação; ou se as alterações de estado global que são causadas pela inicialização estático são onerosas ou devem ser garantido acontecer antes de um método de tipo estático ser chamado ou uma instância do tipo é criada.
Exemplo
O exemplo a seguir mostra um tipo, StaticConstructor, que viola a regra e um tipo, NoStaticConstructor, que substitui o construtor estático com a inicialização embutida para atender a regra.
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");
}
}
}
Observe a adição do sinalizador de beforefieldinit na definição de MSIL para a classe de NoStaticConstructor .
Regras Relacionadas
CA2207: inicializar campos estáticos de tipo de valor embutido