Lambda 执行表达式委托产生空引用异常

Lambda 执行表达式委托产生空引用异常,lambda,expression,nullreferenceexception,Lambda,Expression,Nullreferenceexception,我试图通过解析XML模板来执行在运行时动态创建的方法。在编译表达式lambda之前,我从表达式lambda的“DebugView”中获得以下内容: .Lambda #Lambda1<Reporting.Core.Formatter+WriterDriver>( Reporting.Core.IReportWriter $writer, System.Object $data) { .Block( Reporting.Core.IReportWr

我试图通过解析XML模板来执行在运行时动态创建的方法。在编译表达式lambda之前,我从表达式lambda的“DebugView”中获得以下内容:

.Lambda #Lambda1<Reporting.Core.Formatter+WriterDriver>(
    Reporting.Core.IReportWriter $writer,
    System.Object $data) {
    .Block(
        Reporting.Core.IReportWriter $writer,
        System.Object $data) {
        .Call System.Diagnostics.Trace.WriteLine("Initialize Driver");
        .Call System.Diagnostics.Trace.WriteLine($writer);
        .Block(Reporting.Core.IBannerWriter $bannerWriter) {
            $bannerWriter = .Call $writer.WriteBanner();
            .Call System.Diagnostics.Trace.WriteLine($bannerWriter);
            .Call $bannerWriter.WithLeftEntry(
                "Key1",
                "Value1");
            .Call $bannerWriter.WithLeftEntry(
                "Key 2",
                "Value 2");
            .Call $bannerWriter.WithRightEntry(
                "Another Key",
                "Another Value");
            .Call $bannerWriter.EndBanner()
        }
    }
}
在我的跟踪输出中,在抛出空引用异常之前,我甚至没有得到“初始化驱动程序”输出


仔细查看调试输出可以发现它实际上是“初始化驱动程序”,并在第一个块中添加另一个$writer上的null调试检查。块显示
(writer==null)==true
。现在,问题是:$writer传入方法调用时为什么为null?

第一个.Block中的$writer和$data声明重写了.Lambda中的$writer和$data声明

将表达式生成逻辑更改为:

List<Expression> operations = new List<Expression>();
// populate operations...

var methodBody = Expression.Block(new[] {writer, data}, operations);
var lambda = Expression.Lambda<Action<IReportWrite, Object>>(methodBody, writer, data);
while (lambda.CanReduce) lambda.Reduce();

return lambda.Compile()
列表操作=新建列表();
//填充操作。。。
var methodBody=Expression.Block(新[]{writer,data},operations);
var lambda=Expression.lambda(methodBody、writer、data);
而(lambda.CanReduce)lambda.Reduce();
返回lambda.Compile()
致:

列表操作=新建列表();
//填充操作。。。
var methodBody=Expression.Block(操作);
var lambda=Expression.lambda(methodBody、writer、data);
而(lambda.CanReduce)lambda.Reduce();
返回lambda.Compile()
这产生了一个工作表达式树,如下所示:

.Lambda #Lambda1<Reporting.Core.Formatter+WriterDriver>(
    Reporting.Core.IReportWriter $writer,
    System.Object $data) {
    .Block() {
        .Call System.Diagnostics.Trace.WriteLine("Initialize Driver");
        .Block(Reporting.Core.IBannerWriter $bannerWriter) {
            $bannerWriter = .Call $writer.WriteBanner();
            .Call System.Diagnostics.Trace.WriteLine($bannerWriter);
            .Call $bannerWriter.WithLeftEntry(
                "Key1",
                "Value1");
            .Call $bannerWriter.WithLeftEntry(
                "Key 2",
                "Value 2");
            .Call $bannerWriter.WithRightEntry(
                "Another Key",
                "Another Value");
            .Call $bannerWriter.EndBanner()
        }
    }
}
.Lambda#Lambda1(
Reporting.Core.IReportWriter$writer,
系统对象(数据){
.Block(){
.调用系统.诊断.跟踪.写入线(“初始化驱动程序”);
.Block(Reporting.Core.IBannerWriter$bannerWriter){
$bannerWriter=.Call$writer.WriteBanner();
.呼叫系统.诊断.跟踪.写入线($bannerWriter);
.使用LeftEntry调用$bannerWriter(
“关键1”,
“价值1”);
.使用LeftEntry调用$bannerWriter(
“关键2”,
“价值2”);
.使用RightEntry呼叫$bannerWriter(
“另一把钥匙”,
“另一价值”);
.Call$bannerWriter.EndBanner()
}
}
}
List<Expression> operations = new List<Expression>();
// populate operations...

var methodBody = Expression.Block(operations);
var lambda = Expression.Lambda<Action<IReportWrite, Object>>(methodBody, writer, data);
while (lambda.CanReduce) lambda.Reduce();

return lambda.Compile()
.Lambda #Lambda1<Reporting.Core.Formatter+WriterDriver>(
    Reporting.Core.IReportWriter $writer,
    System.Object $data) {
    .Block() {
        .Call System.Diagnostics.Trace.WriteLine("Initialize Driver");
        .Block(Reporting.Core.IBannerWriter $bannerWriter) {
            $bannerWriter = .Call $writer.WriteBanner();
            .Call System.Diagnostics.Trace.WriteLine($bannerWriter);
            .Call $bannerWriter.WithLeftEntry(
                "Key1",
                "Value1");
            .Call $bannerWriter.WithLeftEntry(
                "Key 2",
                "Value 2");
            .Call $bannerWriter.WithRightEntry(
                "Another Key",
                "Another Value");
            .Call $bannerWriter.EndBanner()
        }
    }
}