私はINotifyPropertyChangedとIDataErrorInfoを実装するバインド可能な基本クラスで作業していますので、WPFにバインドするプロパティを変更通知で書き込んでDataAnnotations検証を使用できるようにしています。この記事へのプロパティゲッターで型を推論できません
賞賛:https://code.msdn.microsoft.com/windowsdesktop/Validation-in-MVVM-using-12dafef3記事は素晴らしいですが、私は臆面もなく
からコピーしてきた、それはので、私は少し物事をクリーンアップしようとしているCallerMemberNameの利点を取ることはありません。
サンプル作成者は、すべてのプライベートプロパティ値を辞書に格納するSetValueメソッドとGetValueメソッドを記述することで、クラス内のプライベートフィールドにプロパティ値を格納するのをスキップできます。著者はこれを行うには4つの機能を使用:
/// <summary>
/// Sets the value of a property.
/// </summary>
/// <typeparam name="T">The type of the property value.</typeparam>
/// <param name="propertySelector">Expression tree contains the property definition.</param>
/// <param name="value">The property value.</param>
protected void SetValue<T>(Expression<Func<T>> propertySelector, T value)
{
string propertyName = GetPropertyName(propertySelector);
SetValue<T>(propertyName, value);
}
/// <summary>
/// Sets the value of a property.
/// </summary>
/// <typeparam name="T">The type of the property value.</typeparam>
/// <param name="propertyName">The name of the property.</param>
/// <param name="value">The property value.</param>
protected void SetValue<T>(string propertyName, T value)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("Invalid property name", propertyName);
}
_values[propertyName] = value;
NotifyPropertyChanged(propertyName);
}
/// <summary>
/// Gets the value of a property.
/// </summary>
/// <typeparam name="T">The type of the property value.</typeparam>
/// <param name="propertySelector">Expression tree contains the property definition.</param>
/// <returns>The value of the property or default value if not exist.</returns>
protected T GetValue<T>(Expression<Func<T>> propertySelector)
{
string propertyName = GetPropertyName(propertySelector);
return GetValue<T>(propertyName);
}
/// <summary>
/// Gets the value of a property.
/// </summary>
/// <typeparam name="T">The type of the property value.</typeparam>
/// <param name="propertyName">The name of the property.</param>
/// <returns>The value of the property or default value if not exist.</returns>
protected T GetValue<T>(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("Invalid property name", propertyName);
}
object value;
if (!_values.TryGetValue(propertyName, out value))
{
value = default(T);
_values.Add(propertyName, value);
}
return (T)value;
}
私は、次の2つにこれらの4つの機能を交換しています
/// <summary>
/// Sets the value of a property.
/// </summary>
/// <typeparam name="T">The type of the property value.</typeparam>
/// <param name="propertyName">The name of the property.</param>
/// <param name="value">The property value.</param>
protected void SetValue<T>(T value, [CallerMemberName] string propertyName = "")
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("Invalid property name", propertyName);
}
_values[propertyName] = value;
NotifyPropertyChanged(propertyName);
}
/// <summary>
/// Gets the value of a property.
/// </summary>
/// <typeparam name="T">The type of the property value.</typeparam>
/// <param name="propertyName">The name of the property.</param>
/// <returns>The value of the property or default value if not exist.</returns>
protected T GetValue<T>([CallerMemberName] string propertyName = "")
{
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("Invalid property name", propertyName);
}
object value;
if (!_values.TryGetValue(propertyName, out value))
{
value = default(T);
_values.Add(propertyName, value);
}
return (T)value;
}
私はそれがいくつかの機能を排除し、メソッドを呼び出して簡略化しているため、それが改善だと思います。次のように
本来の機能を使用してプロパティが実装されている:
[Range(1, 100, ErrorMessage = "Age should be between 1 to 100")]
public int Age
{
get { return GetValue(() => Age); }
set { SetValue(() => Age, value); }
}
以下に示すように、私は私に同じプロパティを実装したいと思います:
[Range(1, 100, ErrorMessage = "Age should be between 1 to 100")]
public int Age
{
get { return GetValue(); }
set { SetValue(value); }
}
唯一の問題は、GetValueメソッドが得られるということです私にエラー:メソッドの
型引数___ GetValueメソッド(文字列)は、」利用状況から推測することはできません。型引数を明示的に指定してみてください。
[Range(1, 100, ErrorMessage = "Age should be between 1 to 100")]
public int Age
{
get { return GetValue<int>(); }
set { SetValue(value); }
}
任意のアイデア:
だから私はこのようにそれを実装する必要がありますか?元のコードが型を推論できる理由はわかりませんが、コードはできません。
GetValueメソッド()を返します。 } 'あなたが' get {return GetValue( "Age"); } 'または何かが足りない? –
@SamIam:いいえ、このメソッドは引数の 'CallerMemberName'属性で文字列を取得しますが、あなたはそれを自分で設定しません。 –
ああ、どんな速度でも、コンパイラが 'GetValue(" Age ")'がintを返すことを設計時に認識することを期待するのはちょっとです。 –