Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the motivation of C# ExpressionVisitor's implementation?

I have to design a solution for a task, and I would like to use something theoretically similar to C#'s ExpressionVisitor.

For curiosity I opened the .NET sources for ExpressionVisitor to have a look at it. From that time I've been wondering why the .NET team implemented the visitor as they did.

For example MemberInitExpression.Accept looks like this:

protected internal override Expression Accept(ExpressionVisitor visitor) {
    return visitor.VisitMemberInit(this);
}

My - probably noob - question is: does it make any sense? I mean shouldn't the Accept method itself be responsible of how it implements the visiting within itself? I mean I've expected something like this (removing the internal visibility to be overridable from outside):

protected override Expression Accept(ExpressionVisitor visitor) {
    return this.Update(
            visitor.VisitAndConvert(this.NewExpression, "VisitMemberInit"),
            visitor.Visit(this.Bindings, VisitMemberBinding)
            );
}

But this code is in the base ExpressionVisitor's VisitMemberInit method, which gets called from MemberInitExpression.Accept. So seems like not any benefit of the Accept implementation here.

Why not just process the tree in the base ExpressionVisitor, and forget about all the Accept methods?

I hope you understand my points, and hope someone could shed some light on the motivation behind this implementation. Probably I don't understand the Visitor pattern at all?...

like image 938
Zoltán Tamási Avatar asked Jan 22 '15 14:01

Zoltán Tamási


People also ask

What is the main point of C?

One of the most significant features of C language is its support for dynamic memory management (DMA). It means that you can utilize and manage the size of the data structure in C during runtime. C also provides several predefined functions to work with memory allocation.

What are 6 C's of motivation?

Through this example, we are brought to learn about what they call the Six C's of motivation: choice, challenge, control, collaboration, constructing meaning, and consequences.

What is motivation explain?

Motivation is derived from the word 'motive,' which denotes a person's needs, desires, wants, or urges. It is the process of motivating individuals to take action in order to achieve a goal. The psychological elements fueling people's behavior in the context of job goals might include a desire for money.

What inspired the invention of C?

The C language was actually created to move the UNIX kernel code from assembly to a higher level language, which would do the same tasks with fewer lines of code. Oracle database development started in 1977, and its code was rewritten from assembly to C in 1983. It became one of the most popular databases in the world.


1 Answers

A visitor can override the way any expression is visited. If your proposal was implemented in all places the visitor never would be called. All the visitation logic would be in the overrides of Accept. Non-BCL code cannot override this method.

If you write visitor.Visit((Expression)this.SomeExpression) (like you do in the question) then how are you going to perform dynamic dispatch on the type of SomeExpression? Now the visitor has to perform the dynamic dispatch. Note, that your 2nd code snippet makes the simplifying assumption that all sub-expressions to be visited have known type. Try to write the code for BinaryExpression to see what I mean.

Maybe I did not understand something but this proposal does not make sense.

The purpose of the Accept method is a performance optimization. Each accept is a virtual call which is rather cheap. The alternative would be to have a huge switch in the visitor over the expression type (which is an enum). That's probably slower.

like image 75
usr Avatar answered Nov 14 '22 23:11

usr