为什么在此表达式树中出现空引用异常?
我有一个如下所示的树表达式:
.Block(
System.Object $instance,
MyType2 $result) {
$result = (MyType2)((MyType1)$instance).Property1;
.Goto return { };
.Label
.LabelTarget useDefault:;
$result = .Default(MyType2);
.Label
.LabelTarget return:;
$result
}
这些是表达式树中使用的自定义类型:
public class MyType1
{
public MyType2 Property1 { get; set; }
}
public class MyType2
{
}
最后,这就是我构建、编译和调用表达式树的方式(这不会完全像这样运行,因为我已经省略了一些代码以简化操作):
object instance = new MyType1();
Expression expression = ... // n => n.Property1
ParameterExpression instanceParameter = Expression.Variable(
typeof(object), "instance");
ParameterExpression resultVariable = Expression.Variable(
typeof(MyType2), "result");
LabelTarget useDefaultLabel = Expression.Label("useDefault");
LabelTarget returnLabel = Expression.Label("return");
List<Expression> targetFragments = new List<Expression>();
MemberInfo memberInfo = (MemberInfo)expression.Body.Member;
MemberExpression member = ConstantExpression.MakeMemberAccess(
Expression.Convert(instanceParameter, memberInfo.DeclaringType),
memberInfo);
targetFragments.Add(
Expression.Assign(
resultVariable,
Expression.Convert(member, typeof(MyType2))));
targetFragments.Add(Expression.Goto(returnLabel));
targetFragments.Add(Expression.Label(useDefaultLabel));
targetFragments.Add(Expression.Assign(resultVariable,
Expression.Default(typeof(MyType2))));
targetFragments.Add(Expression.Label(returnLabel));
targetFragments.Add(resultVariable);
Expression finalExpression = Expression.Block(
new[] { instanceParameter, resultVariable },
targetFragments);
ParameterExpression parameter = Expression.Variable(typeof(object));
MyType2 result = Expression.Lambda<Func<T, MyType2>>(expression, parameter)
.Compile()(instance);
但是调用会抛出以下异常:
未将对象引用设置为对象的实例。在 lambda_method( 闭包 , 对象 )
我认为发生这种情况是因为 $result = (MyType2)((MyType1)$instance).Property1;
赋值,但我不明白为什么,因为该实例传递给表达式的值不为 null
。
I have a tree expression that looks like this:
.Block(
System.Object $instance,
MyType2 $result) {
$result = (MyType2)((MyType1)$instance).Property1;
.Goto return { };
.Label
.LabelTarget useDefault:;
$result = .Default(MyType2);
.Label
.LabelTarget return:;
$result
}
These are the custom types that are used in the expression tree:
public class MyType1
{
public MyType2 Property1 { get; set; }
}
public class MyType2
{
}
Finally, this is how I build, compile and invoke the expression tree (this won't run exactly like this because I've left out some code to simplify things):
object instance = new MyType1();
Expression expression = ... // n => n.Property1
ParameterExpression instanceParameter = Expression.Variable(
typeof(object), "instance");
ParameterExpression resultVariable = Expression.Variable(
typeof(MyType2), "result");
LabelTarget useDefaultLabel = Expression.Label("useDefault");
LabelTarget returnLabel = Expression.Label("return");
List<Expression> targetFragments = new List<Expression>();
MemberInfo memberInfo = (MemberInfo)expression.Body.Member;
MemberExpression member = ConstantExpression.MakeMemberAccess(
Expression.Convert(instanceParameter, memberInfo.DeclaringType),
memberInfo);
targetFragments.Add(
Expression.Assign(
resultVariable,
Expression.Convert(member, typeof(MyType2))));
targetFragments.Add(Expression.Goto(returnLabel));
targetFragments.Add(Expression.Label(useDefaultLabel));
targetFragments.Add(Expression.Assign(resultVariable,
Expression.Default(typeof(MyType2))));
targetFragments.Add(Expression.Label(returnLabel));
targetFragments.Add(resultVariable);
Expression finalExpression = Expression.Block(
new[] { instanceParameter, resultVariable },
targetFragments);
ParameterExpression parameter = Expression.Variable(typeof(object));
MyType2 result = Expression.Lambda<Func<T, MyType2>>(expression, parameter)
.Compile()(instance);
The invoke throws the following exception however:
Object reference not set to an instance of an object. at lambda_method(Closure , Object )
I think this is happening because of the $result = (MyType2)((MyType1)$instance).Property1;
assignment but I don't understand why because the instance that is passed to the expression isn't null
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实是:
毕竟定义的主体应该是线索;本质上,你根本就没有看你传入的对象;您只查看
instanceParameter
,它(在您的代码中)只是一个未分配的变量。基本上,删除最后的
parameter
声明,并且不要将instanceParameter
声明为变量:The fact that:
Is defined after all the body should be the clue; essentially, you simply aren't even looking at the object you pass in; you are only looking at
instanceParameter
, which is (in your code) simply an unassigned variable.Basically, drop the final
parameter
declaration, and don't declareinstanceParameter
as a variable: