Tuesday, February 27, 2007 4:14 AM bart

C# Quiz - call versus callvirt

A little different quiz approach today; starting from IL :-). The question is pretty simple: when does the C# compiler emit a call instruction instead of a callvirt instruction?

A little sample to illustrate the non-trivial character of this question:

1 class Call 2 { 3 static void Main() 4 { 5 C c = new C(); 6 c.Do(); 7 c.DoIt(); 8 } 9 } 10 11 class C 12 { 13 public void Do() {} 14 public virtual void DoIt() {} 15 }

This piece of code will contain two callvirt instructions: one for c.Do() (line 6) and one for c.DoIt() (line 7). A side-question you might ask yourself is why the compiler doesn't emit a call instruction for the non-virtual method call on line 6. Stay tuned for the answer (or find it out yourself :-)).

Have fun!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

# re: C# Quiz - call versus callvirt

Tuesday, February 27, 2007 9:27 AM by Omari

non-virtual call for  Do will emit jit compiller.

advantage that  "this" will be tested for null

# re: C# Quiz - call versus callvirt

Tuesday, February 27, 2007 12:35 PM by Armand du Plessis

The C# compiler will emit a call instruction for static methods and in cases where a virtual method needs to be invoked non-virtually as in the snippet below and in other scenarios it would emit callvirt.

This is to ensure the the receiver is not null and this check is generated by the JIT compiler when using the callvirt instruction. (But Jitted code will still call a non-virtual method directly)

public class D : C

{

  public override void DoIt() {

       base.DoIt(); // Compiler will emit call to invoke DoIt on C non-virtually.

 }

}

When using call the following would still be valid and won't generate NullReferenceException provided Do doesn't reference any instance members of C:

C c = null;

c.Do();