私は最近、我々はデフォルト値で初期化しようとしているならば、我々は...クラス変数を初期化するべきではありません述べた誰かに出くわしました。
私は同意する
、しかし...
これで任意の実際のパフォーマンスの向上がありますか?
いいえ、まったく同じです。違いはスタイルだけの問題です。
もう少し詳しく見ていきましょう。のは、あなたのフラグを設定し、デフォルトにそれを初期化し、それ以外の場合は初期化、およびコンストラクタの両方で実行しないクラスのバリエーションを持ってみましょう:
public class NoInit
{
private bool _flag;
}
public class DefaultInit
{
private bool _flag = false;
}
public class NonDefaultInit
{
private bool _flag = true;
}
public class TestDefaultCtor
{
private bool _flag;
public TestDefaultCtor()
{
_flag = false;
}
}
public class TestNonDefaultCtor
{
private bool _flag;
public TestNonDefaultCtor()
{
_flag = true;
}
}
今リリースビルドをコンパイルすることができます:
.class public auto ansi beforefieldinit NoInit
extends [mscorlib] System.Object
{
.field private bool _flag
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib] System.Object::.ctor()
IL_0006: ret
}
}
.class public auto ansi beforefieldinit DefaultInit
extends [mscorlib] System.Object
{
.field private bool _flag
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib] System.Object::.ctor()
IL_0006: ret
}
}
.class public auto ansi beforefieldinit NonDefaultInit
extends [mscorlib] System.Object
{
.field private bool _flag
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld bool NonDefaultInit::_flag
IL_0007: ldarg.0
IL_0008: call instance void [mscorlib] System.Object::.ctor()
IL_000d: ret
}
}
.class public auto ansi beforefieldinit TestDefaultCtor
extends [mscorlib]System.Object
{
.field private bool _flag
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: ldc.i4.0
IL_0008: stfld bool TestDefaultCtor::_flag
IL_000d: ret
}
}
.class public auto ansi beforefieldinit TestNonDefaultCtor
extends [mscorlib]System.Object
{
.field private bool _flag
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ldarg.0
IL_0007: ldc.i4.1
IL_0008: stfld bool TestNonDefaultCtor::_flag
IL_000d: ret
}
}
ご覧のとおり、フラグをtrueに設定しても影響はありますが(コンストラクタで設定する必要があります)、コンストラクタに設定すると明示的にコンパイルされたfalseに設定されますどんな違いがあっても)、DefaultInit
とNoInit
の間には、それが何であるかに違いはありません〜にmpiled。 C#に逆コンパイルする場合は、明示的にfalseに設定するか、最初の場所に書き込むかのように、独自の呼び出しを行う必要があります。
結果の点では、2つはまったく同じです。
これでは、違いは完全に重要ではありません。 (むしろ、私がやっていたプロジェクトは、一貫して私が気に入らないアプローチを使用していたと思っていましたが、それは非常に矛盾していました。
しかし、多くの初期化はちょっと忙しいかもしれませんし、何らかの型のデフォルトが何であるかを知るのに十分な情報を*追加しないで、特定の値に初期化するときに明確にします。
とにかくコンストラクタの値を設定しようとしている(または時には行く)場合は、特に冗長に思えるかもしれません。 (ただし、デフォルトに初期化すると、コンストラクタの設定は、コンストラクタで設定するだけでなく、デフォルト以外のものに初期化する場合は同じではありません。必ずしもそうではない、特に初期化に副作用がある場合)。
また、デバッグセッション中に信号対雑音比が低下して、面白い初期化が多く発生する可能性があります。
コーディング規約を作成するのは合理的なことだと思いますが、私はそれらの慣習がどのようなものかについてあなたが言及している人に同意しますが、パフォーマンスに影響を与えるものではありません。これらは、デフォルトでは、少なくとも(]は、それぞれ、それらのデフォルトを作るものです)1は、それぞれのクラスまたは名前空間コンテキストにあるかどうかの情報を追加しているので、それは一つの小さなことだところprivate
またはinternal
を使用して対照的に
*読者が考えることが少ない。だから私はそれが明白であることを好みます。
コードを実行して*を見つけます。 – Servy
そのリンクは、 'new int()'についてのみ、 '0'に初期化するのと同じですが、変数を初期化しない*については何も話しません。 – crashmstr
@crashmstr:OPはそのページを、アサーションのソースではなく、デフォルト値である_what_への参照として使用していたと思います。つまり、「私の友人は、変数を初期値(ここでは[https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-表)。" –