考虑以下代码(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):基于第一个答案的更多信息 - 如果您尝试实施Accept,编辑器(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
(我不能这样做)。
答案 0 :(得分:7)
我只是使用Reflector查看.NET 3.5中的LambdaExpression
类,该类只有internal
构造函数。当我尝试你的代码时,我收到一个错误“类型'System.Linq.Expressions.LambdaExpression'没有定义构造函数”,所以在.NET 3.5上这是不可能完成的(抛开它是否有用的问题)做它)。
在.NET 4.0中,它的行为与您所描述的相同。但是,Accept
方法为internal
,StackSpiller
类型也是internal
。这再次意味着您根本无法做到这一点(尽管从编译器错误消息中不清楚)。值得注意的是,该类在.NET 4.0上仍然只有StackSpiller
构造函数。编译器只找到你无法覆盖它的另一个原因(并且不再担心它)。
编辑:关于dynamic
类型 - 它是内部的,所以您不必担心它。但是,它看起来类型来自DLR,它是一个.NET 4.0组件,现在处理lambda表达式的编译(以及C#4 Compile
)。无论如何,DLR是开源的,所以这里是关于这种类型的摘要评论:
表达式重写以将CLR堆栈溢出到临时变量中 为了保证代码生成的某些属性, 我们总是在空堆栈上输入try块的例子。
这意味着当使用{{1}}方法编译lambda表达式时,它用于对lambda表达式进行一些预处理。您可以获得source code from CodePlex。
答案 1 :(得分:4)
错误消息表示LambdaExpression
本身是一个抽象类。您需要为抽象方法Accept
提供身体,或将Foo
声明为抽象。
但是,LambdaExpression
members on MSDN列表未列出Accept
。
答案 2 :(得分:2)
嗯,错误基本上告诉我们LambdaExpression是一个抽象类,这意味着为了从中派生,你必须实现所有抽象成员。在这种情况下,Accept
方法。
答案 3 :(得分:2)
既不推荐也不允许。 LambdaExpression
类型有几个内部抽象成员和一个内部构造函数。这可以防止你从不同的程序集中派生它,除非它们是朋友关系(在这种情况下不存在)