[英]C# Use Expression to get value from an object
object 云是任何 class,我不想使用反射。 这是我的代码:
class Dog
{
public int Id { get; set; }
public string Name { get; set; }
}
static void test()
{
object d = new Dog
{
Id = 21,
Name = "adsf"
};
genericeTest(d);
}
static void genericeTest<T>(T t)
{
var type = t.GetType();
var arg = Expression.Parameter(type, "x");
var expr = Expression.Property(arg, "Id");
var compiled = Expression.Lambda<Func<T, int>>(expr, arg).Compile();
var value = compiled.Invoke(t);
}
但有异常System.ArgumentException: ParameterExpression of type 'ExpressionDemo.Program+Dog' cannot be used for delegate parameter of type 'System.Object'
var compiled = Expression.Lambda<Func<T, int>>(expr, arg).Compile();
如果我这样写
var compiled = Expression.Lambda<Func<Dog, int>>(expr, arg).Compile();
var value = compiled.Invoke(t as Dog);
它运作良好。 我可以修一下吗,谢谢。
问题是您的T
是object
,因为d
的编译时类型为object
,但t.GetType()
是Dog
,因为t
的运行时类型是Dog
。
因此,您有一个接受Dog
的表达式,但您试图将object
类型的变量传递给它——您缺少将object
变成Dog
的演员表。
换句话说,您正在编写的内容大致相当于:
public int GeneratedMethod(object o)
{
Dog d = o; // <-- This line will cause a compile-time error, of course
return d.Id;
}
问题是,您希望生成的方法是什么样的? 它应该看起来像这样吗?
public int GeneratedMethod(object o)
{
Dog d = (Dog)o;
return d.Id;
}
如果是这样,您需要将演员表从object
插入到Dog
。 这样做的方法是使用Expression.Convert
:
var type = t.GetType();
var arg = Expression.Parameter(typeof(T), "x");
var expr = Expression.Property(Expression.Convert(arg, type), "Id");
var compiled = Expression.Lambda<Func<T, int>>(expr, arg).Compile();
在这里,我们声明了一个 lambda ,它接受一个T
,然后将其转换为Dog
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.