It just happens to me about one code design question. Say, I have one \"template\" method that invokes some functions that may \"alter\". A intuitive design is to follow \"Templ
Just wanted to add a few corrections to john skeet's response:
A virtual method call does not need to do a null check (automatically handled with hardware traps).
It also does not need to walk up inheritance chain to find non-overriden methods (that's what the virtual method table is for).
A virtual method call is essentially one extra level of indirection when invoking. It is slower than a normal call because of the table look-up and subsequent function pointer call.
A delegate call also involves an extra level of indirection.
Calls to a delegate do not involve putting arguments in an array unless you are performing a dynamic invoke using the DynamicInvoke method.
A delegate call involves the calling method calling a compiler generated Invoke method on the delegate type in question. A call to predicator(value) is turned into predicator.Invoke(value).
The Invoke method in turn is implemented by the JIT to call the function pointer(s) (stored internally in the delegate object).
In your example, the delegate you passed should have been implemented as a compiler generated static method as the implementation does not access any instance variables or locals so therefore the need to access the "this" pointer from the heap should not be an issue.
The performance difference between delegate and virtual function calls should be mostly the same and your performance tests show that they are very close.
The difference could be due to the need to additional checks+branches because of multicast (as suggested by John). Another reason could be that the JIT compiler does not inline the Delegate.Invoke method and the implementation of Delegate.Invoke does not handle arguments as well as the implementation when performming virtual method calls.