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

发布于 2024-08-22 06:42:22 字数 1410 浏览 6 评论 0原文

考虑以下代码 (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继承自它),但似乎旨在防止继承它。事实真的是这样吗?有谁知道这个方法是关于什么的吗?

编辑 (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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

还不是爱你 2024-08-29 06:42:22

我刚刚使用 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# 4 dynamic)的编译。无论如何,DLR 是开源的,因此以下是关于此类型的摘要评论:

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

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

I just looked at the LambdaExpression class in .NET 3.5 using Reflector and the class has only an internal 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 is internal and so is the StackSpiller 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 only internal 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# 4 dynamic). Anyway, DLR is open-source, so here is what a summary comment says about this type:

Expression rewriting to spill the CLR stack into temporary variables
in order to guarantee some properties of code generation, for
example that we always enter try block on empty stack.

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.

最单纯的乌龟 2024-08-29 06:42:22

该错误消息意味着 LambdaExpression 本身是一个抽象类。您需要为抽象方法 Accept 提供主体,或者将 Foo 声明为抽象。

但是,LambdaExpression 列表MSDN 上的成员 未列出接受

The error message means that LambdaExpression itself is an abstract class. You need either supply your body for abstract method Accept, or declare Foo as abstract.

However, list of LambdaExpression members on MSDN doesn't list Accept.

悟红尘 2024-08-29 06:42:22

好吧,该错误基本上告诉我们 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.

痴意少年 2024-08-29 06:42:22

既不推荐也不允许。 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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文