.NET 中的类可以继承 LambdaExpression 吗?或者不推荐这样做?
考虑以下代码 (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
继承自它),但似乎旨在防止继承它。事实真的是这样吗?有谁知道这个方法是关于什么的吗?
编辑 (1):基于第一个答案的更多信息 - 如果您尝试实现 Accept,编辑器 (C# 2010 Express) 会自动为您提供以下存根:
protected override Expression Accept(System.Linq.Expressions.ExpressionVisitor visitor)
{
return base.Accept(visitor);
}
但您仍然会遇到相同的错误。如果您尝试直接使用 StackSpiller
类型的参数,编译器会抛出不同的错误:System.Linq.Expressions.Compiler.StackSpiller 由于其保护级别而无法访问
。
编辑(2):根据其他答案,不可能从 LambdaExpression 继承,因此是否推荐的问题变得无关紧要。我想知道,在这种情况下,错误消息是否应该是 Foo 无法实现继承的抽象成员 System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller) 因为 [原因在这里]< /代码>;当前的错误消息(正如一些答案所证明的那样)似乎告诉我,我需要做的就是实现
Accept
(我不能这样做)。
Consider the following code (C# 4.0):
public class Foo : LambdaExpression { }
This throws the following design-time error:
Foo does not implement inherited abstract member
System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller)
There's absolutely no problem with public class Foo : Expression { }
but, out of curiosity and for the sake of learning, I've searched in Google System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller)
and guess what: zero results returned (when was the last time you saw that?). Needless to say, I haven't found any documentation on this method anywhere else.
As I said, one can easily inherit from Expression
; on the other hand LambdaExpression
, while not marked as sealed
(Expression<TDelegate>
inherits from it), seems to be designed to prevent inheriting from it. Is this actually the case? Does anyone out there know what this method is about?
EDIT (1): More info based on the first answers - If you try to implement Accept, the editor (C# 2010 Express) automatically gives you the following stub:
protected override Expression Accept(System.Linq.Expressions.ExpressionVisitor visitor)
{
return base.Accept(visitor);
}
But you still get the same error. If you try to use a parameter of type StackSpiller
directly, the compiler throws a different error: System.Linq.Expressions.Compiler.StackSpiller is inaccessible due to its protection level
.
EDIT (2): Based on other answers, inheriting from LambdaExpression is not possible so the question as to whether or not it is recommended becomes irrelevant. I wonder if, in cases like this, the error message should be Foo cannot implement inherited abstract member System.Linq.Expressions.LambdaExpression.Accept(System.Linq.Expressions.Compiler.StackSpiller) because [reasons go here]
; the current error message (as some answers prove) seems to tell me that all I need to do is implement Accept
(which I can't do).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我刚刚使用 Reflector 查看了 .NET 3.5 中的 LambdaExpression 类,该类只有一个内部构造函数。当我尝试您的代码时,我收到错误“类型‘System.Linq.Expressions.LambdaExpression’没有定义构造函数”,因此在 .NET 3.5 上这是无法完成的(不考虑它是否有用的问题)做吧)。
在 .NET 4.0 中,它的行为如您所描述的。但是,
Accept
方法是内部
方法,StackSpiller
类型也是如此。这再次意味着您根本无法执行此操作(尽管从编译器错误消息中尚不清楚)。值得注意的是,该类在 .NET 4.0 上仍然只有内部
构造函数。编译器只会找到您无法覆盖它的另一个原因(并且不再担心它)。编辑:关于
StackSpiller
类型 - 它是内部的,所以你真的不需要担心它。不过,该类型似乎来自 DLR,它是一个 .NET 4.0 组件,现在可以处理 lambda 表达式(以及 C# 4dynamic
)的编译。无论如何,DLR 是开源的,因此以下是关于此类型的摘要评论:这意味着当使用
Compile
方法编译 lambda 表达式时,它用于对 lambda 表达式进行一些预处理。您可以从 CodePlex 获取源代码。I just looked at the
LambdaExpression
class in .NET 3.5 using Reflector and the class has only aninternal
constructor. When I try your code, I'm getting an error "The type 'System.Linq.Expressions. LambdaExpression' has no constructors defined", so on .NET 3.5 this cannot be done (leaving aside the question whether it would be useful to do it).In .NET 4.0 it behaves as you described. However, the
Accept
method isinternal
and so is theStackSpiller
type. This again means that you simply can't do this (although it isn't clear from the compiler error message). It is worth noting that the class still has onlyinternal
constructor on .NET 4.0. The compiler only finds another reason why you can't override it (and doesn't worry about that any more).EDIT: Regarding the
StackSpiller
type - it is internal, so you don't really need to worry about it. However, it looks that the type comes from DLR, which is a .NET 4.0 component that now handles compilation of lambda expressions (and also C# 4dynamic
). Anyway, DLR is open-source, so here is what a summary comment says about this type:This means that it is used to do some pre-processing of lambda expressions when they are compiled using the
Compile
method. You can get the source code from CodePlex.该错误消息意味着 LambdaExpression 本身是一个抽象类。您需要为抽象方法
Accept
提供主体,或者将Foo
声明为抽象。但是,
LambdaExpression
列表MSDN 上的成员 未列出接受
。The error message means that
LambdaExpression
itself is an abstract class. You need either supply your body for abstract methodAccept
, or declareFoo
as abstract.However, list of
LambdaExpression
members on MSDN doesn't listAccept
.好吧,该错误基本上告诉我们 LambdaExpression 是一个抽象类,这意味着为了从它派生,您必须实现所有抽象成员。在本例中为
Accept
方法。Well, the error basically tells us that LambdaExpression is an abstract class, which means that in order to derive from it, you'd have to implement all abstract members. In this case, the
Accept
method.既不推荐也不允许。 LambdaExpression 类型具有多个内部抽象成员和一个内部构造函数。这可以防止您从不同的程序集派生它,除非它们是朋友关系(在本例中不存在)
It is neither recomended or allowed. The
LambdaExpression
type has several internal abstract members and an internal constructor. This prevents you from deriving from it from a different assembly unless their is a friend relationship (which there is not in this case)