Partilhar via


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