[解決済み] INotifyPropertyChangedの実装 - より良い方法は存在するか?
2022-03-14 15:32:19
質問
マイクロソフトは
INotifyPropertyChanged
を指定するだけで、自動生成のプロパティのように
{get; set; notify;}
そうすると、とても理にかなっていると思うんです。それとも、何か複雑な問題があるのでしょうか?
私たち自身が、プロパティに「notify」のようなものを実装することは可能でしょうか。を実装するための優雅な解決策はあるのでしょうか?
INotifyPropertyChanged
を発生させるしかないのでしょうか?
PropertyChanged
イベントを各プロパティで実行します。
を発生させるコードを自動生成するようなものを書けないでしょうか?
PropertyChanged
イベント
解決方法は?
postsharpのようなものを使わずに、私が使っている最小限のバージョンでは、次のようなものを使っています。
public class Data : INotifyPropertyChanged
{
// boiler-plate
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
// props
private string name;
public string Name
{
get { return name; }
set { SetField(ref name, value, "Name"); }
}
}
そうすると、各プロパティは、次のようなものだけです。
private string name;
public string Name
{
get { return name; }
set { SetField(ref name, value, "Name"); }
}
これは巨大なものではありません。必要であれば、ベースクラスとして使用することもできます。そのため
bool
から戻る
SetField
は、他のロジックを適用したい場合に備えて、それがno-opであったかを教えてくれます。
またはC# 5を使えばもっと簡単です。
protected bool SetField<T>(ref T field, T value,
[CallerMemberName] string propertyName = null)
{...}
であり、このように呼び出すことができる。
set { SetField(ref name, value); }
を追加し、コンパイラが
"Name"
を自動生成します。
C# 6.0では、実装が簡単になりました。
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
...そして今度はC#7で。
protected void OnPropertyChanged(string propertyName)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
protected bool SetField<T>(ref T field, T value,[CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
private string name;
public string Name
{
get => name;
set => SetField(ref name, value);
}
そして、C# 8とNullable参照型を使用すると、次のようになります。
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
private string name;
public string Name
{
get => name;
set => SetField(ref name, value);
}
関連
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
[解決済み】バックスラッシュを含むパス文字列のエスケープシーケンスが認識されない件
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み】名前 'ViewBag' が現在のコンテキストに存在しない - Visual Studio 2015
-
[解決済み] C#のオートプロパティに初期値を与える最良の方法は何ですか?
-
[解決済み] C#の[Flags]Enum属性の意味とは?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] C#で文字を繰り返し表示する最適な方法
-
[解決済み] フォルダが存在しない場合、作成する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み】C#で四捨五入する方法
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み】Socket.Selectがエラー "An operation was attempted on something that is not a socket" を返す。
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み】 C# 条件演算子エラー 代入、call、increment、decrement、await、new object 式のみ文として使用可能です。
-
[解決済み】URLから画像をダウンロードする方法