メソッド名を取得するために C#のメソッド を作成しました
_public string GetCorrectPropertyName<T>(Expression<Func<T, string>> expression)
{
return ((MemberExpression)expression.Body).Member.Name; // Failure Point
}
_
そしてそれを
_string lcl_name = false;
public string Name
{
get { return lcl_name ; }
set
{
lcl_name = value;
OnPropertyChanged(GetCorrectPropertyName<ThisClassName>(x => x.Name));
}
}
_
これは、プロパティが文字列の場合は正常に機能し、他のすべてのタイプではこの例外が発生します。
タイプ「System.Linq.Expressions.UnaryExpression」のオブジェクトをタイプ「System.Linq.Expressions.MemberExpression」にキャストできません。
x => x.PropertyName
_からx => Convert.ToString(x.PropertyName)
に変更しましたが、それでも失敗しますどこが間違っているのですか?
入力式が単項式であるメンバーを抽出するには、別の行が必要です。
これをVB.Netから変換しただけなので、少しずれている可能性があります-微調整が必要な場合はお知らせください:
public string GetCorrectPropertyName<T>(Expression<Func<T, Object>> expression)
{
if (expression.Body is MemberExpression) {
return ((MemberExpression)expression.Body).Member.Name;
}
else {
var op = ((UnaryExpression)expression.Body).Operand;
return ((MemberExpression)op).Member.Name;
}
}
VBバージョンは次のとおりです。
Public Shared Function GetCorrectPropertyName(Of T) _
(ByVal expression As Expression(Of Func(Of T, Object))) As String
If TypeOf expression.Body Is MemberExpression Then
Return DirectCast(expression.Body, MemberExpression).Member.Name
Else
Dim op = (CType(expression.Body, UnaryExpression).Operand)
Return DirectCast(op, MemberExpression).Member.Name
End If
End Function
入力式は必ずしも文字列を返すわけではないことに注意してください。これにより、文字列を返すプロパティの読み取りのみに制限されます。
これは どうやら ボクシング/アンボクシングに関連しています。ボクシングを必要とする値の型を返すラムダ式はUnaryExpressionsとして表されますが、参照型を返す式はMemberExpressionsとして表されます。
この質問をした後(はい、私はOPです) Jon から質問に対するコメントを受け取りました
これを思いついた
public string ResolvePropertyName<TEntity>(Expression<Func<TEntity>> expression)
{
try {
if (expression == null) {
Throw New ArgumentNullException("propertyExpression")
}
object memberExpression = expression.Body as MemberExpression;
if (memberExpression == null) {
Throw New ArgumentException("The expression is not a member access expression.", "propertyExpression")
}
object property = memberExpression.Member as PropertyInfo;
if (property == null) {
Throw New ArgumentException("The member access expression does not access a property.", "propertyExpression")
}
object getMethod = property.GetGetMethod(true);
if (getMethod.IsStatic) {
Throw New ArgumentException("The referenced property is a static property.", "propertyExpression")
}
return memberExpression.Member.Name;
} catch (Exception ex) {
return string.Empty;
}
}