一个类可以继承.NET中的LambdaExpression吗?或者这不推荐?

时间:2010-02-20 18:56:11

标签: c# .net inheritance lambda

考虑以下代码(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):基于第一个答案的更多信息 - 如果您尝试实施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(我不能这样做)。

4 个答案:

答案 0 :(得分:7)

我只是使用Reflector查看.NET 3.5中的LambdaExpression类,该类只有internal构造函数。当我尝试你的代码时,我收到一个错误“类型'System.Linq.Expressions.LambdaExpression'没有定义构造函数”,所以在.NET 3.5上这是不可能完成的(抛开它是否有用的问题)做它)。

在.NET 4.0中,它的行为与您所描述的相同。但是,Accept方法为internalStackSpiller类型也是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类型有几个内部抽象成员和一个内部构造函数。这可以防止你从不同的程序集中派生它,除非它们是朋友关系(在这种情况下不存在)