考虑以下代码(C#4.0):

public class Foo : LambdaExpression { }

这将引发以下设计时错误:

Foo does not implement inherited abstract member
System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller)


public class Foo : Expression { }绝对没有问题,但是出于好奇并出于学习的目的,我在Google System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller)中进行搜索并猜测是什么:返回零结果(您上次看到该结果的时间是什么?)。不用说,我在其他任何地方都找不到关于此方法的任何文档。

正如我所说,可以很容易地从Expression继承;另一方面,LambdaExpression虽然未标记为sealedExpression<TDelegate>从其继承),但似乎旨在防止从其继承。真的是这样吗?外面有人知道这种方法是什么吗?

编辑(1):基于第一个答案的更多信息-如果您尝试实现接受,则编辑器(C#2010 Express)会自动为您提供以下存根:

protected override Expression Accept(System.Linq.Expressions.ExpressionVisitor visitor)
{
    return base.Accept(visitor);
}


但是您仍然会遇到相同的错误。如果尝试直接使用类型为StackSpiller的参数,则编译器将引发另一个错误:System.Linq.Expressions.Compiler.StackSpiller is inaccessible due to its protection level

编辑(2):基于其他答案,无法从LambdaExpression继承,因此有关是否建议使用的问题变得无关紧要。我想知道在这种情况下,错误消息是否应为Foo cannot implement inherited abstract member System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller) because [reasons go here];当前的错误消息(如一些答案所证明)似乎告诉我,我需要做的只是实现Accept(我做不到)。

最佳答案

我只是使用Reflector查看了.NET 3.5中的LambdaExpression类,该类只有一个internal构造函数。当我尝试您的代码时,出现错误“类型'System.Linq.Expressions。LambdaExpression'尚未定义构造函数”,因此在.NET 3.5上无法完成(撇开它是否有用的问题做到)。

在.NET 4.0中,其行为与您描述的相同。但是,Accept方法是internalStackSpiller类型也是如此。同样,这意味着您根本无法做到这一点(尽管从编译器错误消息中看不出来)。值得注意的是,该类在.NET 4.0上仍然只有internal构造函数。编译器只会发现您无法覆盖它的另一个原因(并且不再担心)。

编辑:关于StackSpiller类型-它是内部类型,因此您实际上不必担心它。但是,该类型似乎来自DLR,它是一个.NET 4.0组件,现在可以处理lambda表达式(以及C#4 dynamic)的编译。无论如何,DLR是开源的,因此以下是对此类型的简要评论:


  表达式重写将CLR堆栈溢出到临时变量中
  为了保证代码生成的某些特性,
  我们总是在空堆栈上输入try块的示例。


这意味着,当使用Compile方法编译lambda表达式时,它可用于对其进行一些预处理。您可以获取source code from CodePlex

10-04 10:16