Interface Dispatch: VTable vs Interface Map (ITable)
1Concept
While class virtual methods are resolved via direct VTable indexing, interface method calls (`callvirt`) require looking up the class's Interface Map (ITable), adding a level of indirection.
2Architecture Diagram
Class Virtual Call: Object ──> MethodTable ──> VTable[Index] ──> Direct Jump Interface Call: Object ──> MethodTable ──> Interface Map ──> Interface Slot ──> VTable[Index] ──> Jump
3Code Example
C# 13 & .NET 9
using System;
public interface IDataStore
{
void Save(string key, string data);
}
public sealed class MemoryDataStore : IDataStore
{
public void Save(string key, string data)
{
Console.WriteLine($"[Store] Key: '{key}' saved with data payload: '{data}'");
}
}
public class InterfaceDispatchDemo
{
public static void Main()
{
IDataStore store = new MemoryDataStore();
store.Save("session_99", "{ active: true }");
}
}4Expected Output
[Store] Key: 'session_99' saved with data payload: '{ active: true }'5Key Takeaways
- ✓Sealing the implementation class allows RyuJIT to devirtualize interface calls.
- ✓Use interface abstractions at module boundaries; use concrete types in hot inner loops.
- ✓Interface method dispatch is fast but carries 1 extra pointer hop compared to sealed calls.