Partilhar via


CA1810: Inicializar embutido de campos estáticos do tipo de referência

TypeName

InitializeReferenceTypeStaticFieldsInline

CheckId

CA1810

<strong>Categoria</strong>

Microsoft.Performance

Alteração significativa

Não-separável

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 just-in-time (JIT) adiciona uma verificação para cada método e instância o construtor estático do tipo para certificar-se de que o construtor estático era anteriormente chamado. Inicialização estática é disparada quando qualquer membro estático é acessado ou quando uma instância do tipo é criada. No entanto, a inicialização estática não é disparada se você declara uma variável do tipo, mas não usá-lo, que pode ser importante se a inicialização altera o estado global.

Quando todos os dados estáticos é inicializado embutido e não está declarado como um construtor estático explícito, compiladores do Microsoft intermediate language (MSIL) é adicionar o beforefieldinit sinalizador e um construtor estático implícito, que inicializa dados estáticos, a definição de tipo MSIL. Quando o compilador JIT encontra o beforefieldinit Sinalizar, na maioria das vezes, as verificações de construtor estático não são adicionadas. Inicialização estática certamente ocorrer em algum momento, antes de quaisquer campos estáticos são acessados, mas não antes de um construtor estático de instância ou método é invocado. Observe que a inicialização estática pode ocorrer a qualquer momento depois de uma variável do tipo é declarada.

Verificações do construtor estático podem diminuir o desempenho. Geralmente, um construtor estático é usado apenas para inicializar os campos estáticos, no qual o caso, você deve apenas Certifique-se que a inicialização estática ocorre antes do primeiro acesso de um campo estático. O beforefieldinit comportamento é apropriado para essas e mais outros tipos. Somente é inadequado quando inicialização estática afeta o estado global e uma das seguintes opções for verdadeira:

  • O efeito sobre o estado global é caro e não será necessário se o tipo não é usado.

  • Os efeitos de estado global podem ser acessados sem acessar todos os campos do tipo estáticos.

Como corrigir violações

Para corrigir uma violação desta regra, inicializar todos os dados estáticos quando ela é declarada e remover o construtor estático.

Quando suprimir avisos

É seguro eliminar um aviso esta regra se o desempenho não é uma preocupação; ou se as alterações de estado global são causadas pela inicialização estática são caras ou devem ser garantida para ocorrer antes que um método estático do tipo é 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 inicialização embutido para satisfazer 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 da beforefieldinit o sinalizador na definição de MSIL para o NoStaticConstructor classe.

  

Regras relacionadas

CA2207: Inicializar o tipo de valor campos estáticos in-line