WPFを使用することで、INotifyPropertyChangedのファンになりました。式を受け取り、名前を文字列として返すヘルパーを使用するのが好きです(以下のサンプルコードを参照)。しかし、非常に熟練したプログラマーが目にする多くのアプリケーションでは、文字列を生で処理するコードが見られます(以下の2番目の例を参照)。熟練とは、エクスプレッションの使い方を知っているMVPタイプを意味します。
私にとって、簡単なリファクタリングに加えて、コンパイラーにミスをキャッチさせる機会は、Exressionアプローチをより良くします。私が見逃している生の文字列を使用することに賛成する議論はありますか?
乾杯、ベリール
式ヘルパーの例:
public static string GetPropertyName<T>(Expression<Func<T, object>> propertyExpression)
{
Check.RequireNotNull<object>(propertyExpression, "propertyExpression");
switch (propertyExpression.Body.NodeType)
{
case ExpressionType.MemberAccess:
return (propertyExpression.Body as MemberExpression).Member.Name;
case ExpressionType.Convert:
return ((propertyExpression.Body as UnaryExpression).Operand as MemberExpression).Member.Name;
}
var msg = string.Format("Expression NodeType: '{0}' does not refer to a property and is therefore not supported",
propertyExpression.Body.NodeType);
Check.Require(false, msg);
throw new InvalidOperationException(msg);
}
生の文字列のサンプルコード(一部のViewModelBase型クラス):
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG"), DebuggerStepThrough]
public void VerifyPropertyName(string propertyName) {
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null) {
string msg = "Invalid property name: " + propertyName;
if (ThrowOnInvalidPropertyName) throw new Exception(msg);
else Debug.Fail(msg);
}
}
/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }