.NET CIL Call or CallVirt?

How to determine whether to call a method using "Call" or "Callvirt"?

+6
c # cil
source share
3 answers

You can follow these simple rules one by one to determine what you should use:

  • Is the method static ? Then use call .
  • Is the type you are calling for the type of value used? Then use call . (This does not apply if the value is inserted into the box - then you are actually calling on object or some interface, and these are reference types.)
  • Is the method you call declared virtual or abstract ? Then use callvirt .
  • Are you calling a method through a link to an interface? Then use callvirt .
  • Is the method called that you call the declared override called, but neither the method nor the declared type are declared sealed ? Then use callvirt .

In all other cases, virtual sending is not required, so you can use call - but you must use callvirt . That's why:

Using callvirt for non-virtual methods is equivalent to call , unless the first argument is null. In this case, callvirt immediately throw a NullReferenceException , while call will not. This makes sense, since callvirt designed to be used in cases where you need to send a virtual method, and you cannot send a virtual method if you do not have an object for which you can search in vtable.

Note that callvirt will still throw an exception if the first argument is zero, even if vtable search is not needed!

Given this information, using callvirt for all non-static method calls in reference types (as the C # compiler does) may be preferable, as this will cause an immediate NullReferenceException to be NullReferenceException at the call site, and not sometime later when this used ( explicitly or implicitly) inside a method.

+4
source share

By default, the C # compiler always uses callvirt for all but calls of type static or value. This leads to an implicit check of the zero of the argument 'this' (arg0). You do not have to follow this convention, but callvirt is required for any virtual method in the reference type.

+6
source share

If you use a call in a dynamic method of a virtual method, the runtime generates a security exception.

0
source share

All Articles