I am trying to invoke an internal method from a dynamically generated one. The il code is simple: ldarg_0, callvirt, ret.
Executing the method fails with TypeLoadException saying it cannot load the type on which the internal method is defined.
When I think of it, this seems logical, because the dynamic method host assembly is not a friend of the method's declaring type assembly.
However, I have expected the dynamic method still to work, just like Delegate.CreateDelegate works. After all, I did manage to get the MethodInfo of the internal method, so the permissions barrier are behind me.
Anyway, the question is "is it possible to invoke an internal method from a dynamically generated one?"
Thanks.
EDIT:
Here is a simple code sample demonstrating the problem:
using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
namespace A
{
internal class Data
{
internal string String { get; set; }
}
public static class Program
{
public static void Main()
{
Expression<Func<Data, string>> expr = x => x.String;
var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true);
var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo);
var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) });
var gen = dm.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Castclass, typeof(Data));
gen.Emit(OpCodes.Callvirt, getterInfo);
gen.Emit(OpCodes.Ret);
var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>));
var data = new Data() { String = "Hello" };
var str1 = getter1(data);
var str2 = getter2(data);
}
}
}
In the code I create two open instance delegates to access the Data.String instance property:
- type safe getter1 using Delegate.CreateDelegate
- type unsafe getter2 using DynamicMethod
The type safe delegate created by Delegate.CreateDelegate works, while the one using DynamicMethod fails with the TypeLoadException.
Note, that I do not wish to take the type safe approach, since the context where the getter is created is not generic. Of course, I can solve this issue, but the question is now that of principal - why DynamicMethod fails where Delegate.CreateDelegate succeeds?
It will work if you skip visibility checks.
Change this line
See msdn: (in particular the table with all the rules.)
This is from the doco on the constructor.