CA1810:参照型の静的フィールドをインラインで初期化します
プロパティ | 値 |
---|---|
ルール ID | CA1810 |
Title | 参照型の静的フィールドをインラインで初期化します |
[カテゴリ] | パフォーマンス |
修正が中断ありか中断なしか | なし |
.NET 9 では既定で有効 | いいえ |
原因
参照型で明示的な静的コンストラクターを宣言しています。
規則の説明
型で明示的な静的コンストラクターを宣言すると、Just-In-Time (JIT) コンパイラが、静的コンストラクターが呼び出されたことを確認するために、型の静的メソッドと静的インスタンス コンストラクターに個別にチェックを追加します。 静的な初期化は、静的メンバーへのアクセス時または型のインスタンスの作成時にトリガーされます。 ただし、静的な初期化は、型の変数を宣言しても使用しない場合にはトリガーされません。これは、初期化によってグローバル状態が変更される場合に重要になることがあります。
すべての静的データがインラインで初期化され、明示的な静的コンストラクターが宣言されていない場合、共通中間言語 (CIL) コンパイラは、 beforefieldinit
フラグと、静的データを初期化する暗黙的な静的コンストラクターを CIL 型定義に追加します。 JIT コンパイラが beforefieldinit
フラグを検出したとき、ほとんどの場合、静的コンストラクター チェックは追加されません。 静的な初期化は、静的フィールドにアクセスされる前に発生することは保証されていますが、静的メソッドまたは静的インスタンス コンストラクターが呼び出される前に発生することは保証されていません。 静的な初期化は、型の変数が宣言された後、任意の時点で発生する可能性があることに注意してください。
静的コンストラクターのチェックによってパフォーマンスが低下することがあります。 多くの場合、静的コンストラクターは、静的フィールドを初期化するためにのみ使用されます。その場合、静的フィールドに最初にアクセスする前にのみ静的な初期化が行われるようにする必要があります。 beforefieldinit
動作は、これらおよびその他のほとんどの型に適しています。 静的な初期化がグローバル状態に影響し、次のいずれかに該当する場合のみ、不適切です。
グローバル状態への影響のコストが高く、型が使用されていない場合は必要ない。
グローバル状態の効果に、型の静的フィールドにアクセスせずにアクセスできる。
違反の修正方法
この規則違反を修正するには、静的データが宣言されたとき、および静的コンストラクターを削除するときに、静的データをすべて初期化します。
どのようなときに警告を抑制するか
次のいずれかが当てはまる場合、この規則による警告を抑制しても問題ありません。
- パフォーマンスは問題ではない。
- 静的な初期化によって発生するグローバル状態の変更は高くつきます。あるいは型の静的メソッドが呼び出されるか型のインスタンスが作成される前に確実に行う必要があります。
警告を抑制する
単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。
#pragma warning disable CA1810
// The code that's violating the rule is on this line.
#pragma warning restore CA1810
ファイル、フォルダー、またはプロジェクトの規則を無効にするには、構成ファイルでその重要度を none
に設定します。
[*.{cs,vb}]
dotnet_diagnostic.CA1810.severity = none
詳細については、「コード分析の警告を抑制する方法」を参照してください。
例
次の例は、規則に違反する型 StaticConstructor
、および規則に適合するように静的コンストラクターをインライン初期化に置き換える型 NoStaticConstructor
を示しています。
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 void Print()
{
Console.WriteLine(someInteger);
}
}
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");
}
public void Print()
{
Console.WriteLine(someInteger);
}
}
Imports System
Imports System.Resources
Namespace ca1810
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()
Private Shared Function InitializeResourceString()
Dim stringManager As New ResourceManager("strings",
System.Reflection.Assembly.GetExecutingAssembly())
Return stringManager.GetString("string")
End Function
End Class
End Namespace
NoStaticConstructor
クラスの CIL 定義に beforefieldinit
フラグが追加されていることに注意してください。
.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
関連規則
.NET