title: How come delegate objects are allowed to call internal methods?
body: <p>I can easily wrap a call to an internal method inside a delegate. The delegate can then call this method when I call <code>Invoke()</code>. However, the delegate is in the <code>mscorlib</code> assembly. Why can it call an internal method from my assembly?</p>
  
  <p>Obviously, a delegate must be able to do this for C# to work properly. The question is not <em>why</em> it's allowed. It's <em>how</em>.</p>
  
  <p>I assumed checking for visibility was a C# feature and that calling the method from CIL directly should just work. So I tried to just call that method from a dynamically defined type, thus using CIL directly and skipping C#. It failed miserably. Here's the code:</p>
  
  <pre><code>public static class InternalCall
  {
      internal static void InternalMethod()
      {
          Debug.WriteLine("Successfully called an internal method from: " + typeof(InternalCall).Assembly.FullName);
      }
  
      public interface IMyAction
      {
          void MyInvoke();
      }
  
      private static IMyAction MakeMyAction()
      {
          var assembly = Thread.GetDomain().DefineDynamicAssembly(new AssemblyName("Outside"), AssemblyBuilderAccess.Run);
          var module = assembly.DefineDynamicModule("Outside", false);
          var customType = module.DefineType("MyAction",
              TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit,
              typeof(object),
              new[] { typeof(IMyAction) });
          var method = customType.DefineMethod("MyInvoke",
              MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final);
          var il = method.GetILGenerator();
          il.Emit(OpCodes.Call, typeof(InternalCall).GetMethod("InternalMethod", BindingFlags.Static | BindingFlags.NonPublic));
          il.Emit(OpCodes.Ret);
  
          return (IMyAction)customType.CreateType().GetConstructor(Type.EmptyTypes).Invoke(null);
      }
  
      public static void RunTest()
      {
          var action = new Action(InternalMethod);
          Debug.WriteLine("Calling via action from assembly: " + action.GetType().Assembly.FullName);
          action.Invoke();
  
          var myAction = MakeMyAction();
          Debug.WriteLine("Calling via my type from assembly: " + myAction.GetType().Assembly.FullName);
          myAction.MyInvoke(); // MethodAccessException
      }
  }
  </code></pre>
  
  <p>So, assuming delegates are still abiding by CIL rules (since that is what C# compiles to), what CIL mechanism are they using to call any method regardless of visibility?</p>