考虑以下代码(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
虽然未标记为sealed
(Expression<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
方法是internal
,StackSpiller
类型也是如此。同样,这意味着您根本无法做到这一点(尽管从编译器错误消息中看不出来)。值得注意的是,该类在.NET 4.0上仍然只有internal
构造函数。编译器只会发现您无法覆盖它的另一个原因(并且不再担心)。
编辑:关于StackSpiller
类型-它是内部类型,因此您实际上不必担心它。但是,该类型似乎来自DLR,它是一个.NET 4.0组件,现在可以处理lambda表达式(以及C#4 dynamic
)的编译。无论如何,DLR是开源的,因此以下是对此类型的简要评论:
表达式重写将CLR堆栈溢出到临时变量中
为了保证代码生成的某些特性,
我们总是在空堆栈上输入try块的示例。
这意味着,当使用Compile
方法编译lambda表达式时,它可用于对其进行一些预处理。您可以获取source code from CodePlex。