-1

C#でセッターなしでプロパティのオブジェクトを初期化する最良の方法は何ですか?

たとえば、タイプ UserData のプロパティがあり、それを初期化できます。

  1. コンストラクタで
  2. ゲッターで

    private UserData _user;
    
    public UserData User  
    {  
        get  
        {  
            return _user?? (_user= new UserData ());  
        }  
    }
    
  3. フィールドの初期化:

    private UserData _user = new UserData()

類似のスレッドはほとんど見つかりませんでした。コンストラクター内またはクラスC# メンバー変数
の初期化の先頭でオブジェクトを作成します。
ベストプラクティス?

しかし、それは 1 番目と 3 番目のオプションの間の考慮事項です - 誰も 2 番目のオプションについて考えていません - 方法を知っていますか? しばらくの間、オブジェクトを取得するのが私の好ましいオプションですが、私が知らないいくつかの短所があるのではないかと思います。

最適なオプションと、2 番目のオプションを利用できる問題を教えてください。

4

3 に答える 3

3

それはすべてあなたがそれで何をしたいかによるので、それには明確な答えがあります.

1+3 と 2 の違いの 1 つは予測可能性です。
1+3 を使用すると、オブジェクトが作成された場所と、クラスのインスタンス化中の時点が正確にわかります。これは、状況によっては望ましい場合があります。
2 では、外部の影響 (誰がいつプロパティにアクセスするか) に依存してフィールドを初期化します。

アプローチ 2 の遅延作成 (必要な場合にのみオブジェクトを作成する) を使用すると、含まれているクラスのオブジェクトを作成するときに時間を節約できます。

の作成に時間がかかる場合UserData(データベースにクエリを実行する必要がある場合など) は、本当に必要になるまで作成を遅らせることができます。UserDataオブジェクトが作成されるのを待つ必要がないため、オブジェクトを含むオブジェクトはより速く構築UserDataされます。プロパティが常にアクセスされるとは限らない場合、UserDataインスタンスの作成を完全に回避できる場合もあります。

于 2012-07-25T14:08:57.687 に答える
0

単純なデータを使用している場合は、その定義でバッキング フィールドを初期化することをお勧めします (可能な場合)。

// when you create constructor N+1, no worries about forgetting to set the value
private UserData _userData = new UserData();

public UserData User
{
    get { return _userData; }
}

初期化を延期する必要がある場合、最適なオプションは次を使用することLazy<T>です。

private Lazy<UserData> _userData = new Lazy<UserData>(() => new UserData());

public UserData User
{
    get { return _userData.Value; }
}    

のコンストラクターにLazy<T>は、スレッド セーフのニーズに対応できるオーバーロードが含まれています。

  • None: 複数のスレッドからのアクセスは「未定義の動作」です
  • PublicationOnly: 初期化を完了した最初のスレッドが「勝ちます」
  • ExecutionAndPublication: ロックは、1 つのスレッドのみが値を初期化することを保証します
于 2012-07-25T14:17:32.463 に答える
0

#2 の 1 つの問題は、複数のスレッドがプロパティにアクセスできる場合、UserData オブジェクトのコピーが 2 つ作成される可能性があることです。#2 に関する追加の考慮事項は、UserData を作成するのにコストがかかる場合、そのオブジェクトを作成するコストは、それを含むオブジェクトが作成されるときではなく、プロパティがアクセスされるときに支払うことになります。ユースケースによっては、それが望ましい場合とそうでない場合があります。

于 2012-07-25T14:42:17.247 に答える