24

デフォルトのデフォルト値をフィールドに割り当てる場合 (ここでは bool に false)、FxCop は次のように言います。

Resolution   : "'Bar.Bar()' initializes field 'Bar.foo' 
               of type 'bool' to false. Remove this initialization 
               because it will be done automatically by the runtime."

今、私はそのコードがいくらかの冗長性を導入している、int a = 0または導入していることを知っていますbool ok = falseが、私の意見では、私の教師が正当に主張した非常に優れたコード実践のように思えます。

パフォーマンスの低下が非常に小さいだけでなく、さらに重要なことは、デフォルトに依存することは、デフォルトに付属するすべてのデータ型で、コードの一部を使用する各プログラマーの知識に依存することです。(日付時刻?)

真剣に、私はこれは非常に奇妙だと思います: あまりにも明白な間違いからあなたを守るはずのまさにそのプログラムが、パフォーマンスをいくらか向上させるためだけに、ここでそれを作ることを提案しています? (ここでは、一度だけ実行される初期化コードについて話しているのです! それだけ気にするプログラマーは、もちろん初期化を省略できます (おそらく C またはアセンブラーを使用する必要があります :-) )。

FxCop はここで明らかな間違いを犯していますか?

2 つの更新:

  1. これは私の意見ではなく、大学(ベルギー)で教えられたことです。私は論拠アドベレカンディアムを使用したいわけで はありませんが、それが私の意見だけではないことを示すためです. そしてそれに関して:

  2. 申し訳ありませんが、これを見つけました:

    オブジェクトフィールドを常にデフォルト値に初期化する必要がありますか?

4

6 に答える 6

11

場合によっては、これによりパフォーマンスが大幅に向上する可能性があります。詳細については、この CodeProject の記事を参照してください。

主な問題は、C# では不要だということです。C++ では状況が異なるため、多くの教授は常に初期化する必要があると教えています。オブジェクトが初期化される方法は、.NET で変更されました。

.NET では、オブジェクトは構築時に常に初期化されます。初期化子を追加すると、変数の二重初期化が発生する可能性があります (通常)。これは、コンストラクタまたはインラインで初期化するかどうかに関係なく発生します。

さらに、初期化は .NET では不要であるため (明示的にデフォルトに初期化するように言わなくても、常に発生します)、初期化子を追加すると、読みやすさの観点から、関数。すべてのコードには目的があり、不要であれば削除する必要があります。「余分な」コードは、たとえそれが無害であっても、保守性を低下させる理由があることを示唆しています。

于 2009-04-08T17:26:41.860 に答える
6

Reed Copsey は、フィールドにデフォルト値を指定するとパフォーマンスに影響を与えると述べ、2005 年のテストについて言及しています。

public class A
{
    // Use CLR's default value
    private int varA;
    private string varB;
    private DataSet varC;
}

public class B
{
    // Specify default value explicitly
    private int varA = 0;
    private string varB = null;
    private DataSet varC = null;
}

8 年と 4 つのバージョンの C# と .NET を使用した後、Visual Studio 2012 を使用して既定の最適化でリリースとしてコンパイルされた .NET Framework 4.5 と C# 5 でテストを繰り返すことにしました。まだパフォーマンスの違いがあることに驚きました。フィールドをデフォルト値で明示的に初期化することと、デフォルト値を指定しないことの間。私は、後の C# コンパイラがこれらの定数の割り当てを最適化することを期待していたでしょう。

初期化なし: 512,75 Def の初期化: 536,96 Const の初期化: 720,50
メソッド初期化なし: 140,11 定義上のメソッド初期化: 166,86

(残り)

Aだから私はクラスのコンストラクターとBこのテストの内部をのぞき見しましたが、両方とも空です:

.method public hidebysig specialname rtspecialname 
    instance void .ctor () cil managed 
{
    // Code size 7 (0x7)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: call instance void [mscorlib]System.Object::.ctor()
    IL_0006: ret
} // end of method .ctor

デフォルトの定数値をフィールドに明示的に割り当てると時間がかかる理由を IL で見つけることができませんでした。どうやら C# コンパイラ定数を最適化して取り除いているようです。

したがって、テストは間違っているに違いありません... クラスAとの内容を交換Bし、結果文字列の数値を交換し、テストを再実行しました。そして見よ、突然デフォルト値を指定する方が速くなりました。

初期化なし: 474,75 Def の初期化: 464,42 Const の初期化: 715,49
メソッド初期化なし: 141,60 定義上のメソッド初期化: 171,78

(残り)

したがって、C# コンパイラは、フィールドにデフォルト値を割り当てる場合に正しく最適化すると結論付けています。性能差はありません!


これで、パフォーマンスが実際には問題ではないことがわかりました。そして、私はReed Copsey の声明に同意しません

長期的なメンテナンスを考えてください。

  • コードはできるだけ明示的にしてください。
  • 必要がない場合は、言語固有の初期化方法に依存しないでください。おそらく、言語の新しいバージョンでは動作が異なるでしょうか?
  • 将来のプログラマーはあなたに感謝します。
  • 運営はよろしくお願いします。
  • 少しでも難読化するのはなぜですか?

将来のメンテナは異なるバックグラウンドから来るかもしれません。何が「正しい」かということではなく、長期的には何が最も簡単かということです。

于 2013-04-02T14:55:43.657 に答える