views:

177

answers:

4

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).

+3  A: 

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.

Vlad
+2  A: 

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.

CodingInsomnia
+6  A: 

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.

Tomas Petricek
+1: thanks a lot for investigating this in more detail (and great book btw). I'm going to wait and see if someone out there knows more about this `Compiler.StackSpiller` thing...
d.
I added some info about `StackSipller`.
Tomas Petricek
Great stuff - Thanks a lot!
d.
+2  A: 

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)

JaredPar