CA1810. Инициализируйте статические поля ссылочных типов при объявленииCA1810: Initialize reference type static fields inline

TypeNameTypeName InitializeReferenceTypeStaticFieldsInlineInitializeReferenceTypeStaticFieldsInline
CheckIdCheckId CA1810CA1810
КатегорияCategory Microsoft.PerformanceMicrosoft.Performance
Критическое изменениеBreaking Change Не критическоеNon-breaking

ПричинаCause

Ссылочный тип объявляет явный статический конструктор.A reference type declares an explicit static constructor.

Описание правилаRule description

Если в типе объявляется явный статический конструктор, компилятор JIT добавляет проверку в каждый статический метод и конструктор экземпляров этого типа, чтобы убедиться, что статический конструктор уже вызывался ранее.When a type declares an explicit static constructor, the just-in-time (JIT) compiler adds a check to each static method and instance constructor of the type to make sure that the static constructor was previously called. Статическая инициализация выполняется при доступе к статическому члену, или при создании экземпляра типа.Static initialization is triggered when any static member is accessed or when an instance of the type is created. Тем не менее статическая инициализация не выполняется, если объявить переменную типа, но его не следует использовать, что может быть важно в том случае, если инициализация изменения глобального состояния.However, static initialization is not triggered if you declare a variable of the type but do not use it, which can be important if the initialization changes global state.

При всех статических данных является встроенным инициализированный и явный статический конструктор не объявлен, компиляторы Microsoft промежуточного языка MSIL добавляют beforefieldinit флаг и неявный статический конструктор, который инициализирует статические данные, к типу MSIL Определение.When all static data is initialized inline and an explicit static constructor is not declared, Microsoft intermediate language (MSIL) compilers add the beforefieldinit flag and an implicit static constructor, which initializes the static data, to the MSIL type definition. Когда JIT-компилятор встречает beforefieldinit флаг, в большинстве случаев проверки статических конструкторов не добавляются.When the JIT compiler encounters the beforefieldinit flag, most of the time the static constructor checks are not added. Статическая инициализация будет гарантированно выполнена прежде, чем к статическим полям осуществляется, но не перед вызывается статический конструктор, метод или экземпляр.Static initialization is guaranteed to occur at some time before any static fields are accessed but not before a static method or instance constructor is invoked. Обратите внимание, что статическая инициализация может произойти в любое время после объявления переменной типа.Note that static initialization can occur at any time after a variable of the type is declared.

Проверки статических конструкторов могут привести к снижению производительности.Static constructor checks can decrease performance. Часто статический конструктор используется только для инициализации статических полей, в которых необходимо только убедиться в том статическая инициализация происходит до первого обращения статического поля.Often a static constructor is used only to initialize static fields, in which case you must only make sure that static initialization occurs before the first access of a static field. beforefieldinit Поведение подходит для этих и большинства других типов.The beforefieldinit behavior is appropriate for these and most other types. Он не только может использоваться, когда статическая инициализация влияет на глобальное состояние и одно из следующих условий верно:It is only inappropriate when static initialization affects global state and one of the following is true:

  • Воздействие на глобальное состояние ресурсоемких и не является обязательным, если тип не используется.The effect on global state is expensive and is not required if the type is not used.

  • Изменение глобального состояния может осуществляться без доступа к любой статические поля типа.The global state effects can be accessed without accessing any static fields of the type.

Устранение нарушенийHow to fix violations

Чтобы устранить нарушение данного правила, выполните инициализацию всех статических данных при их объявлении и удалите статический конструктор.To fix a violation of this rule, initialize all static data when it is declared and remove the static constructor.

Отключение предупрежденийWhen to suppress warnings

Это безопасно подавить предупреждение из этого правила, если производительность не имеет значения; или если изменения глобального состояния, вызванные статическая инициализация дороги или необходимо гарантировать должно происходить перед вызывается статический метод типа или создается экземпляр типа.It is safe to suppress a warning from this rule if performance is not a concern; or if global state changes that are caused by static initialization are expensive or must be guaranteed to occur before a static method of the type is called or an instance of the type is created.

ПримерExample

В следующем примере показано типом, StaticConstructor, нарушает правило и тип NoStaticConstructor, который заменяет статический конструктор на встроенную инициализацию в соответствии с правилом.The following example shows a type, StaticConstructor, that violates the rule and a type, NoStaticConstructor, that replaces the static constructor with inline initialization to satisfy the rule.

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");
      }
   }
}
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

Обратите внимание, добавление beforefieldinit флагом в определении MSIL для NoStaticConstructor класса.Note the addition of the beforefieldinit flag on the MSIL definition for the NoStaticConstructor class.

.class public auto ansi StaticConstructor
extends [mscorlib]System.Object
{
} // end of class StaticConstructor

.class public auto ansi beforefieldinit NoStaticConstructor
extends [mscorlib]System.Object
{
} // end of class NoStaticConstructor