public static IConditional Compile(AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index) { TypeBuilder typeBuilder = assembly.DefineType( $"__conditional{index}", TypeAttributes.Public, typeof(object)); { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); for (int i = 0; i < conditions.Length; ++i) { conditions[i].Construct(typeBuilder, il, i); } // return; il.Emit(OpCodes.Ret); } typeBuilder.AddInterfaceImplementation(typeof(IConditional)); MethodBuilder compareMethod; { MethodEmitter emitter = new MethodEmitter(typeBuilder); emitter.Define( /* name */ "Verify", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof(bool), /* params */ new[] { typeof(object) }); LocalBuilder obj = emitter.CreateLocal(objectType); LocalBuilder eq = emitter.CreateLocal(typeof(bool)); emitter.LoadArgument(1); emitter.CastAs(objectType); emitter.StoreLocal(obj); Label done = emitter.CreateLabel(); for (int i = 0; i < conditions.Length; ++i) { if (i > 0) { emitter.LoadLocal(eq); emitter.BranchIfFalse(done); } emitter.LoadLocal(obj); conditions[i].Compile(emitter); emitter.StoreLocal(eq); } emitter.MarkLabel(done); emitter.LoadLocal(eq); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof(IConditional).GetMethod( "Verify", new[] { typeof(object) }) !); compareMethod = emitter.Method; } Type conditionalType = typeBuilder.CreateType(); return(conditionalType.CreateInstance <IConditional>()); }
public static IConditional Compile( AssemblyEmitter assembly, Type objectType, ICondition[] conditions, int index ) { TypeBuilder typeBuilder = assembly.DefineType( "__conditional" + index, TypeAttributes.Public, typeof( object ) ); #region Constructor { ConstructorBuilder ctor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes ); ILGenerator il = ctor.GetILGenerator(); // : base() il.Emit( OpCodes.Ldarg_0 ); il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) ); for ( int i = 0; i < conditions.Length; ++i ) conditions[i].Construct( typeBuilder, il, i ); // return; il.Emit( OpCodes.Ret ); } #endregion #region IComparer typeBuilder.AddInterfaceImplementation( typeof( IConditional ) ); MethodBuilder compareMethod; #region Compare { MethodEmitter emitter = new MethodEmitter( typeBuilder ); emitter.Define( /* name */ "Verify", /* attr */ MethodAttributes.Public | MethodAttributes.Virtual, /* return */ typeof( bool ), /* params */ new Type[] { typeof( object ) } ); LocalBuilder obj = emitter.CreateLocal( objectType ); LocalBuilder eq = emitter.CreateLocal( typeof( bool ) ); emitter.LoadArgument( 1 ); emitter.CastAs( objectType ); emitter.StoreLocal( obj ); Label done = emitter.CreateLabel(); for ( int i = 0; i < conditions.Length; ++i ) { if ( i > 0 ) { emitter.LoadLocal( eq ); emitter.BranchIfFalse( done ); } emitter.LoadLocal( obj ); conditions[i].Compile( emitter ); emitter.StoreLocal( eq ); } emitter.MarkLabel( done ); emitter.LoadLocal( eq ); emitter.Return(); typeBuilder.DefineMethodOverride( emitter.Method, typeof( IConditional ).GetMethod( "Verify", new Type[] { typeof( object ) } ) ); compareMethod = emitter.Method; } #endregion #endregion Type conditionalType = typeBuilder.CreateType(); return (IConditional) Activator.CreateInstance( conditionalType ); }