C# 无法将“System.Linq.Expressions.UnaryExpression”类型的对象转换为“System.Linq.Expressions.MemberExpression”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12420466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'System.Linq.Expressions.MemberExpression'
提问by Nikhil Agrawal
I created a method in C#to get methodname
public string GetCorrectPropertyName<T>(Expression<Func<T, string>> expression)
{
return ((MemberExpression)expression.Body).Member.Name; // Failure Point
}
and calling it as
并将其称为
string lcl_name = false;
public string Name
{
get { return lcl_name ; }
set
{
lcl_name = value;
OnPropertyChanged(GetCorrectPropertyName<ThisClassName>(x => x.Name));
}
}
This works fine if property is string and for all other types gives this exception:
如果属性是字符串并且对于所有其他类型给出此异常,则这可以正常工作:
Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'System.Linq.Expressions.MemberExpression'.
无法将“System.Linq.Expressions.UnaryExpression”类型的对象转换为“System.Linq.Expressions.MemberExpression”类型。
- I changed string to object in method signature, but then it fails again.
- I changed calling from
x => x.PropertyNametox => Convert.ToString(x.PropertyName)and it still fails
- 我在方法签名中将字符串更改为对象,但随后又失败了。
- 我将呼叫从 更改
x => x.PropertyName为x => Convert.ToString(x.PropertyName),但仍然失败
Where am I wrong?
我哪里错了?
采纳答案by Jon Egerton
You need a separate line to extract the Member where the input expression is a Unary Expression.
您需要一个单独的行来提取成员,其中输入表达式是一元表达式。
Just converted this from VB.Net, so might be slightly off - let me know if I need to make any minor tweaks:
刚刚从 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;
}
}
The VB version is:
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
Note that the input expression does not return string necessarily - that constrains you to only reading properties that return strings.
请注意,输入表达式不一定返回字符串 - 这限制了您只能读取返回字符串的属性。
回答by Nikhil Agrawal
After asking this question(yes I am OP) i received comments on question from Jon
问这个问题后(是的,我是 OP),我收到了Jon对问题的评论
and I came up with this
我想出了这个
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;
}
}
回答by Scott Munro
This is apparentlyrelated to boxing/unboxing. Lambda expressions returning value types that require boxing will be represented as UnaryExpressions whereas those that return reference types will be represented as MemberExpressions.
这显然与装箱/拆箱有关。返回需要装箱的值类型的 Lambda 表达式将表示为 UnaryExpressions,而返回引用类型的表达式将表示为 MemberExpressions。

