C#6.0では、get-onlyプロパティを定義する機能が導入されています。
public ICommand AddCommand { get; }
次のような別のプロパティを定義するとき、ReSharperは自動プロパティをget-onlyにすることができます:を提案します。
private List<Screenshot> Screenshots { get; set; }
さらに、ReSharperは、プライベートゲッターを定義するときに何も言いません。
public ICommand AddCommand { get; private set; }
パブリックget-onlyプロパティ(最初のAddCommand
など)、プライベートget-onlyプロパティ(Screenshots
プロパティなど)、およびパブリックプライベートセッタープロパティ(など)の違いは何ですか2番目のAddCommand
)?
私のWPFアプリケーションは、パブリックプロパティ(UICommand)にプライベートセッターが含まれているか、セッターがまったく含まれていないかを気にしていないようですが、確かに違いがあるはずですか?
コマンドをバインドするこの特定のケースでは、それは実際には重要ではありません。
その他の場合、つまり、コンストラクターを介してサービスを注入するクラスがあり、それを(何らかの理由で)公開したい場合は、読み取り専用プロパティを使用することが重要です。
例えば:
_public class MainViewModel
{
public INavigationService NavigationService { get; }
public MainViewModel(INavigationService navigationService)
{
if(navigationService == null)
throw new ArgumentNullException(navigationServie);
NavigationService = navigationService;
}
}
_
これを使用する場合、このクラスの不変条件を保証し、NavigationService
がnull
になることはないことを保証します。したがって、使用する前にNavigationService
に対してnullチェックを行う必要はありません。コンストラクターを離れると、変更することはできません(リフレクションを除く)。
あなたが持っている場合は反対側に
_public class MainViewModel
{
public INavigationService NavigationService { get; private set; }
public MainViewModel(INavigationService navigationService)
{
if(navigationService == null)
throw new ArgumentNullException(navigationServie);
NavigationService = navigationService;
}
}
_
次に、_NavigationService = null
_を実行するコードを(誤ってまたは経験の浅い開発者が)作成する可能性があります。nullチェックを行わずにアクセスすると、NullReferenceException
が取得され、処理されない場合はアプリケーションがクラッシュします。
例に戻ります。ICommand
...の場合、通常はViewModel内のコマンドにアクセスせず、割り当てるだけです(通常、コンストラクターで、または子ビューモデルが変更されて割り当てたいビューモデルのコンテンツが変更された場合)。親のviewmodelコマンドプロパティへのコマンドです)。
リストの場合:
コードでScreenshots = new List<ScreenShot>()
またはScreenshots = DisplayScreenshots()
を実行せず、コンストラクターで初期化するだけの場合は、同じ理由で読み取り専用にすることをお勧めします。Screenshots
を保証できます。 nullになることはなく、次のようなコードを記述する必要はありません。
_if(Screenshots != null)
{
Screenshots.Add(new Screenshot(...));
}
_
または
_if(Screenshot == null)
{
Screenshots = new List<Screenshot>();
}
Screenshots.Add(new Screenshot(...));
_
繰り返し、代わりに常に使用します
_Screenshots.Add(new Screenshot(...));
_
これには、必要なコードが少なくて済み、コードが読みやすく、保守しやすいという大きな利点があります。これは、nullチェックを「忘れて」、NullReferenceException
のリスクを冒すことはできないためです。
それがそれをクリアしたことを願っています。
短い答え:
public ICommand AddCommand { get; }
readonly
フィールドによってサポートされ、コンストラクターの実行を超えてC#コードで変更することはできません。
また、プロパティアクセサがないため、コンパイラはバッキングフィールドを直接割り当てるコードを生成します。
一方:
public ICommand AddCommand { get; private set; }
readonly
以外のフィールドでバックアップされ、プライベートメンバーにアクセスできる任意のコードでいつでも割り当てることができます。
この場合、コンパイラは通常のプロパティ設定コードを生成します。
外の世界にとって、プライベートセッターはそれが存在しないかのようです。つまり、実際には存在しなかったのと同じです。
コンパイラが宿題をした後のプロパティは次のようになります。
1.1。public ICommand AddCommand { get; }
:
private readonly ICommand <AddCommand>k__BackingField;
public ICommand AddCommand {
get { return this.<AddCommand>k__BackingField; }
}
2.2。private List<Screenshot> Screenshots { get; set; }
:
private List<Screenshot> <Screenshots>k__BackingField;
private List<Screenshot> Screenshots {
get { return this.<Screenshots>k__BackingField; }
set { this.<Screenshots>k__BackingField = value; }
}
3.3。public ICommand AddCommand { get; private set; }
:
private ICommand <AddCommand>k__BackingField;
public ICommand AddCommand {
get { return this.<AddCommand>k__BackingField; }
private set { this.<AddCommand>k__BackingField = value; }
}
つまり、publicget-onlyプロパティはコンストラクターでのみ割り当てることができます (フィールドが読み取り専用であるため)またはこの新しい構文によって:
public ICommand AddCommand { get; } = new MyCommand();
しかし、他の読み取り専用フィールドに関しては、このコードはとにかくコンストラクターに入れられるので、大きな違いはありません。
public MyClass1()
{
this.<AddCommand>k__BackingField = new MyCommand();
}