1

C#では、次の違いがありますか

//syntax 1
    private ICommand newWindowCommand;
    public ICommand NewWindowCommand
    {
        get
        {
            return newWindowCommand = newWindowCommand ?? new MVVM.RelayCommand(...);
        }
    }

    //syntax 2
    private ICommand newWindowCommand;
    public ICommand NewWindowCommand
    {
        get
        {
            return  newWindowCommand ?? new MVVM.RelayCommand(...);
        }
    }

    //syntax 3 the usual way 


    private ICommand newWindowCommand;
    public ICommand NewWindowCommand
    {
        get
        {
            if (newWindowCommand==null)
            {
                newWindowCommand = new MVVM.RelayCommand(...);
            }
            return newWindowCommand;
        }
     }

ケース 2 では、newWindowCommand を返された値に設定しますか、それともケース 1 のように割り当てる必要がありますか?

4

5 に答える 5

2

ケース 2 は設定されないnewWindowCommandため、new MVVM.RelayCommand(...);毎回呼び出されます。

于 2013-11-05T09:23:57.357 に答える
2

ケース 2 と 3 は機能的には同じですが、IL が異なり、最適化によっては、スレッド セーフなどに関して異なる特性を持つ可能性があります。このコードの問題が特定されていない限り、これを選択することはお勧めしません。

するかどうか

get {
    return newWindowCommand ?? (newWindowCommand = new MVVM.RelayCommand(...));
}

また

get {
    return newWindowCommand = newWindowCommand ?? new MVVM.RelayCommand(...);
}

後者の余分な割り当てが冗長になる可能性があるため、おそらく同じ最適化されたコードになるでしょう。

これらすべてを使用する別のオプションがありますLazy<T>

  Lazy<IComand> newWindowCommand = new Lazy<ICommand>(()=> new MVVM.RelayCommand(...));
  get {
    return newWindowCommand.Value;
  }

たとえば、スレッドセーフに関して、初期化をさらにカスタマイズできます。スレッドの安全性に関する懸念がない場合は、より読みやすく、意図を最も純粋に表現していると思われるものを使用することをお勧めします。スレッドの安全性に懸念Lazy<T>がある場合は、どちらが読みやすいと思うかに関係なく、使用することをお勧めします。スレッド セーフを正しく設定するのは難しいため、可能な場合は常に BCL 実装を使用します。

于 2013-11-05T11:46:25.107 に答える
1

コード内の別の場所で newWindowCommand フィールドを設定しない限り、ケース 1 と 2 では常に null になります。

この種の遅延初期化の別のこと。複数のスレッドがコマンド プロパティに同時にアクセスする場合、新しい RelayCommand を複数回初期化できます。コードを同期する必要があります。

get
{
    lock(syncobject)
    {
        return newWindowCommand ?? (newWindowCommand = MVVM.RelayCommand(...));
    }
}

ICommand メソッドは、バインド以外の状況ではおそらく使用されません。バインド メカニズムはコマンドを 1 回だけ取得するため、コマンド参照をビューモデルに保存する必要はおそらくないでしょう。

public ICommand NewWindowCommand
{
    get
    {
        return new MVVM.RelayCommand(...);
    }
} 
于 2013-11-05T09:41:41.493 に答える
1

確かに、構文 2 の場合、は初期化されたnewWindowCommandままになります (null)

于 2013-11-05T09:24:06.963 に答える