I have a function:
private string GetPropertyName(Expression<Func<object, object>> f) {
if ((f.Body as MemberExpression) != null) {
return (f.Body as MemberExpression).Member.Name;
}
return "";
}
And it is used this way:
string x1 = GetPropertyName(x => Property1);
string x2 = GetPropertyName(x => Property2);
string x3 = GetPropertyName(x => Property3);
where Property1 is an int, Proper开发者_开发百科ty2 is a string, and Property3 is an object...
Only the names of Property2 and Property3 of types string and object respectfully are correctly returned, but Property1's f.Body as MemberExpression is null...
Why is this so, and how can we change the code so the function returns the Properties' names correctly?
I guess the problem is that x => Property1
expression contains implicit cast to object.
Compiler adds such cast to fulfil arguments of GetPropertyName.
You should check for this cast
private string GetPropertyName(Expression<Func<object, object>> f) {
var body = f.Body;
if (body.NodeType==ExpressionType.Convert)
body = ((UnaryExpression) body).Operand;
if ((body as MemberExpression) != null) {
return (body as MemberExpression).Member.Name;
}
return "";
}
There is a boxing operation happening under the covers: The int
is boxed in order to pass as an object
.
To avoid further problems, I'd recommend changing the signature of your method and make it generic:
private string GetPropertyName<T, TResult>(Expression<Func<T, TResult>> f) {
// ...
}
This is entirely untested but it should resolve your issue; The use of generics should avoid the necessity to box or convert anything (implicitly).
int, double, and bool are native types in C# - that is, they are not objects at all. In other words, there is no class definition for int - it's an interpretation of a value in raw memory. Therefore, all of the method calls that you can do on classes derived from Object fail. I'm not as familiar with C#'s introspection capabilities, so I'm afraid that I can't give you specific advice on how to fix it.
精彩评论