I get an exception for the following code:
public class InnerClass
{
public object Value { get; set; }
}
public class OuterClass
{
// If I change the type of this property to "InnerClass" the exception is removed
public object Inner { get; set; }
}
private static void SmallSandbox()
{
var outer = new OuterClass()
{
Inner = new InnerClass()
{
Value = 2
}
};
var p = Expression.Parameter(typeof(OuterClass), "p");
Func<OuterClass, object> e = Expression.Lambda<Func<OuterClass, object>>(
Expression.Property(Expression.Property(p, "Inner"), "Value"),
p
).Compile();
var a = new[] { outer }.Select(e).First();
Console.WriteLine(a);
}
Changing public object Inner { get; set; }
public object Inner { get; set; }
public object Inner { get; set; }
to public InnerClass Inner { get; set; }
public InnerClass Inner { get; set; }
public InnerClass Inner { get; set; }
removes the exception. This is not an option because I'm having the consumer of my program ultimately provide the property name "Value"
and the associated object - It can't be known ahead.
What can I do to fix my exception?
Inner
is declared as an object
. And clearly, an object
doesn't contain a Value
property. You need to "convert" that expression to the expected type before you attempt to access that property. This is equivalent to adding a cast to the expression.
Func<OuterClass, object> e = Expression.Lambda<Func<OuterClass, object>>(
Expression.Property(
Expression.Convert(Expression.Property(p, "Inner"), typeof(InnerClass)),
"Value"
),
p
).Compile();
this seem to work...
using Microsoft.CSharp.RuntimeBinder;
var p = Expression.Parameter(typeof(OuterClass), "p");
var binder = Binder.GetMember(CSharpBinderFlags.None, "Value", outer.Inner.GetType(), new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
var e = Expression.Lambda<Func<OuterClass, object>>(
Expression.Dynamic(binder, typeof(object) ,Expression.Property(p, "Inner")),
p
).Compile();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.