更新: これは、C# 6 からの問題ではなくなりました。C# 6 では、この
nameof
ようなシナリオに対処するためにオペレーターが導入されました ( MSDNを参照)。注:「<a href="https://stackoverflow.com/questions/11063502/getting-names-of-local-variables-and-parameters-at-run-time-through-lambda-exp">取得」を参照してくださいこの質問の一般化といくつかの回答については、実行時のラムダ式によるローカル変数 (およびパラメーター) の名前を参照してください。
Eric De Carufelによって提供されたものと同様のコードを使用して、ラムダ式を使用してINotifyPropertyChanged
インターフェイスのリファクタリング セーフな実装を作成するというアイデアが気に入っています。
ArgumentException
リファクタリング セーフな方法で (またはその派生クラス) にパラメーター名を提供するために、同様の実装を試しています。
null
チェックを実行するための次のユーティリティ メソッドを定義しました。
public static void CheckNotNull<T>(Expression<Func<T>> parameterAccessExpression)
{
Func<T> parameterAccess = parameterAccessExpression.Compile();
T parameterValue = parameterAccess();
CheckNotNull(parameterValue, parameterAccessExpression);
}
public static void CheckNotNull<T>(T parameterValue,
Expression<Func<T>> parameterAccessExpression)
{
if (parameterValue == null)
{
Expression bodyExpression = parameterAccessExpression.Body;
MemberExpression memberExpression = bodyExpression as MemberExpression;
string parameterName = memberExpression.Member.Name;
throw new ArgumentNullException(parameterName);
}
}
引数の検証は、次の構文を使用してリファクタリング セーフな方法で実行できます。
CheckNotNull(() => arg); // most concise
CheckNotNull(arg, () => args); // equivalent, but more efficient
私の懸念は次の行にあります。
Expression bodyExpression = parameterAccessExpression.Body;
MemberExpression memberExpression = bodyExpression as MemberExpression;
AMemberExpression
は「フィールドまたはプロパティへのアクセス」を表します。INotifyPropertyChanged
この場合、ラムダ式はプロパティ アクセスになるため、正しく動作することが保証されています。
ただし、上記のコードでは、ラムダ式は意味的にはパラメーターアクセスであり、フィールドまたはプロパティ アクセスではありません。コードが機能する唯一の理由は、C# コンパイラが匿名関数でキャプチャされたローカル変数 (およびパラメーター) を、舞台裏でコンパイラによって生成されたクラス内のインスタンス変数に昇格させるためです。これは、 Jon Skeetによって裏付けられています。
私の質問は次のとおりです。この動作 (キャプチャされたパラメーターをインスタンス変数に昇格させる) は .NET 仕様内で文書化されていますか、それとも代替実装またはフレームワークの将来のリリースで変更される可能性のある単なる実装の詳細ですか? 具体的には、parameterAccessExpression.Body is MemberExpression
返品する環境はありますfalse
か?