2009-05-26 3 views
0

自動プロパティがある場合、C#コンパイラは、すべてのコンストラクタでthisコンストラクタを呼び出して、アクセスする前にすべてが初期化されていることを確認するように求めます。構造体でこれを使用することのオーバーヘッド

自動プロパティを使用せず、単に値を宣言する場合は、thisコンストラクタの使用を避けることができます。

構造体のコンストラクタにthisを使用すると、どのようなオーバーヘッドが発生しますか?値を二重に初期化するのと同じですか?

パフォーマンスがこの特定のタイプで最も懸念されていた場合は、使用しないことをおすすめしますか?

答えて

4

構造体には自動プロパティを使用しないことをお勧めします。これは、私的にしか変更できないことを意味します。

readonlyフィールドと公開プロパティを使用して、適切な場所にアクセスできるようにします。変更可能な構造は、ほとんど常に悪い考えであり、あらゆる種類の厄介な小さないたずらを持っています。

最初に独自の値型を作成する必要はありますか?私の経験では、それは非常にではなく、クラスではなく構造体を作成する良い理由を見つけることです。あなたが持っているかもしれないが、チェックする価値がある。

元の質問に戻る:パフォーマンスについて気になる場合は、を測定するととなります。常に。この場合、それは本当に簡単です - あなたは、自動プロパティを使用して構造体を記述し、それを使わずに再実装することができます。 #ifブロックを使用して、両方のオプションを使用可能にすることができます。次に、典型的な状況を測定し、その違いが重要かどうかを確認することができます。もちろん、とにかくデザインの意義がもっと重要になると思います。

+0

ありがとうございました。あなたの返事を見ました。自動プロパティは可変性を意味します、どのように?私はautoプロパティのsetキーワードでプライベートを使用すると、それが不変になると思いましたか?また、不変型の値を設定する際のしきい値は何ですか?それらをコンストラクタ内に設定するのは問題ありません。 –

+1

これは正しく変更できません。つまり、型内でのみ変更することができます。それは小さな違いのように見えるかもしれませんが、私はそれが重要なものだと信じています。もちろん、コンストラクタ内でreadonly変数を好きなだけ設定できます。 –

+0

お返事ありがとうございました。 –

2

はい、値は2回初期化され、プロファイリングなしではこのパフォーマンスヒットが重要かどうかを判断するのが難しいです。

structのデフォルトコンストラクタは、すべてのメンバーをデフォルト値に初期化します。この後、コンストラクタが実行され、間違いなくそれらのプロパティの値が再度設定されます。

これは、インスタンス化時に参照型のすべてのフィールドを初期化するCLRのプラクティスと変わらないと思います。 すべての変数はコンストラクタを終了する前に割り当てる必要があるため

+0

しかし、それが自動プロパティの場合、デフォルト値になると思いますよね? intの場合は0、文字列の場合はnull? –

+1

自動プロパティであっても、それをバックアップするフィールドがまだあります。フィールドの値は、その型のデフォルト値(integals = 0、reference types = nullなど)に設定されます。 –

+0

Andrewに感謝します。ただ好奇心から、積分では整数を意味しますか?それとも同じものなのでしょうか? –

1

C#コンパイラがデフォルトコンストラクタにチェーンにあなたを必要とした理由は、(すなわち、あなたのコンストラクタ宣言に: this()を追加)自動実装プロパティを使用しているときです。さて、自動実装されたプロパティーは、これをちょっと説明しています。プロパティーを戻す変数に直接アクセスすることはできません。コンパイラがこれを回避するために使用するメソッドは、すべての変数をデフォルト値に自動的に割り当てることです。これを保証するには、デフォルトのコンストラクタにチェーンする必要があります。それは特に巧妙な方法ではありませんが、十分にうまくいっています。

実際、これはいくつかの変数が2回初期化されることになります。しかし、私はこれが大きなパフォーマンス上の問題になるとは思わない。私は非常にコンパイラ(または少なくともJIT)は、単にコンストラクタで2回設定されている任意の変数の最初の初期化ステートメントを削除していない驚くだろう。私はあなたが疑わしい結果を得ることは確かですが、クイックベンチマークでこれを確認してください。 (偶然ではなく、重複した初期化のオファーを避けるために、わずかなパフォーマンスの向上が絶対に必要な場合は、バッキング変数を使用して、通常の方法でプロパティを定義することができます)。構造内の自動実装プロパティを気にすることさえありません。パブリック変数の代わりにパブリック変数を使用するだけで、自動実装されたプロパティより少ない機能性を提供できます。クラスはもちろん別の状況ですが、私は実際に構造体の中でパブリック変数を使用することを躊躇しません。 (複雑なプロパティは、必要に応じて通常どおり定義できます)

希望するものがあります。

1

構造タイプで自動プロパティを使用しないでください。フィールドを直接公開するだけです。構造体がBarの公開公開フィールドFooを持つ場合、Fooというタイプの公開フィールドは、Bar(Intellisenseから容易に入手可能な情報)のフィールドであることがわかります。対照的に、構造体Fooが公開された読み書きプロパティーBozを持っているということは、Bozへの書き込みが構造体のフィールドを変更するかどうか、またはBozが参照を保持するオブジェクトを変更するかどうかについては何も言いません。フィールドを直接公開すると、よりクリーンなセマンティクスが提供され、実行速度の速いコードになることもよくあります。

関連する問題