Need a unique gift idea?
A Pastebin account makes a great Christmas gift
SHARE
TWEET

Untitled

a guest Mar 13th, 2018 51 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. using System.Linq;
  2. using System.Reflection;
  3. using System.Reflection.Emit;
  4.  
  5. namespace DP115Test
  6. {
  7.     using System;
  8.  
  9.     class Program
  10.     {
  11.         static void Main(string[] args)
  12.         {
  13.             var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Foo"), AssemblyBuilderAccess.RunAndSave);
  14.             var type = assembly
  15.                 .DefineDynamicModule("FooModule", "FooModule.dll", true)
  16.                 .DefineType("AClass", TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit, typeof(object), new[] { typeof(IFoo) });
  17.             var method = type.DefineMethod("IFoo.SomeMethod", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis);
  18.             var typeParameters = method.DefineGenericParameters(new[] { "TBase", "TInherited" });
  19.             typeParameters[1].SetBaseTypeConstraint(typeParameters[0]);
  20.             type.DefineMethodOverride(method, typeof(IFoo).GetMethods().Single());
  21.             ConstructorBuilder nestedCtor;
  22.             MethodBuilder nestedMethod;
  23.             TypeBuilder nested = GenerateInvocationType(type, method, out nestedCtor, out nestedMethod);
  24.             GenerateSomeMethod(method, nested, typeParameters, nestedCtor, nestedMethod);
  25.             var createdType = type.CreateType();
  26.             nested.CreateType();
  27.             assembly.Save("FooModule.dll");
  28.  
  29.             var instance = Activator.CreateInstance(createdType) as IFoo;
  30.             //instance.SomeMethod<IComparable<string>, string>(); // NOTE: will currently yield StackOverflowException
  31.         }
  32.  
  33.         private static TypeBuilder GenerateInvocationType(TypeBuilder type, MethodBuilder method, out ConstructorBuilder nestedCtor, out MethodBuilder nestedMethod)
  34.         {
  35.             var builder = type.DefineNestedType("NestedClass",
  36.                                                 TypeAttributes.AutoLayout | TypeAttributes.AnsiClass |
  37.                                                 TypeAttributes.Serializable |
  38.                                                 TypeAttributes.Sealed | TypeAttributes.NestedAssembly, typeof (object),
  39.                                                 new[] {typeof (IInvocation)});
  40.             var typeParameters = builder.DefineGenericParameters(new[] {"TBase_NestedType", "TInherited_NestedType"});
  41.             typeParameters[1].SetBaseTypeConstraint(typeParameters[0]);
  42.             var target = builder.DefineField("target", type, FieldAttributes.InitOnly | FieldAttributes.Private);
  43.             nestedCtor = GenerateCtor(type, builder, target);
  44.             nestedMethod = GenerateInvokeOnTarget(type, builder, target, typeParameters, method);
  45.             return builder;
  46.         }
  47.  
  48.         private static MethodBuilder GenerateInvokeOnTarget(TypeBuilder type, TypeBuilder builder, FieldBuilder target, GenericTypeParameterBuilder[] parameters, MethodBuilder methodToInvoke)
  49.         {
  50.             var method = builder.DefineMethod("InvokeOnTarget",
  51.                                               MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot |
  52.                                               MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis);
  53.             method.SetReturnType(typeof(void));
  54.             var generator = method.GetILGenerator();
  55.             generator.Emit(OpCodes.Ldarg_0);
  56.             generator.Emit(OpCodes.Ldfld, target);
  57.             generator.Emit(OpCodes.Callvirt, methodToInvoke.MakeGenericMethod(parameters));
  58.             generator.Emit(OpCodes.Ret);
  59.             return method;
  60.         }
  61.  
  62.         private static ConstructorBuilder GenerateCtor(TypeBuilder type, TypeBuilder builder, FieldBuilder target)
  63.         {
  64.             var constructor =
  65.                 builder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
  66.                                           CallingConventions.HasThis, new Type[] {type});
  67.             var generator = constructor.GetILGenerator();
  68.             generator.Emit(OpCodes.Ldarg_0);
  69.             generator.Emit(OpCodes.Call, typeof (object).GetConstructors().Single());
  70.             generator.Emit(OpCodes.Ldarg_0);
  71.             generator.Emit(OpCodes.Ldarg_1);
  72.             generator.Emit(OpCodes.Stfld, target);
  73.             generator.Emit(OpCodes.Ret);
  74.             return constructor;
  75.         }
  76.  
  77.         private static void GenerateSomeMethod(MethodBuilder method, TypeBuilder invocation, GenericTypeParameterBuilder[] parameters, ConstructorBuilder nestedCtor, MethodBuilder nestedMethod)
  78.         {
  79.             method.SetReturnType(typeof(void));
  80.  
  81.             var genericType = invocation.MakeGenericType(parameters);
  82.             var constructor = TypeBuilder.GetConstructor(genericType, nestedCtor);
  83.             var methodInfo = TypeBuilder.GetMethod(genericType,nestedMethod);
  84.             var generator = method.GetILGenerator();
  85.             generator.Emit(OpCodes.Ldarg_0);
  86.             generator.Emit(OpCodes.Newobj, constructor);
  87.             generator.Emit(OpCodes.Callvirt, methodInfo);
  88.             generator.Emit(OpCodes.Ret);
  89.         }
  90.     }
  91.  
  92.     public interface IFoo
  93.     {
  94.         void SomeMethod<TBase, TInherited>() where TInherited : TBase;
  95.     }
  96.  
  97.     public interface IInvocation
  98.     {
  99.         void InvokeOnTarget();
  100.     }
  101. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top