Advanced .NET Programming I 9th Lecture

Slides:



Advertisements
Similar presentations
Practical Malware Analysis
Advertisements

Mike Barnett RSDE Microsoft Research Nikolai Tillmann RSDE Microsoft Research TL51.
Chapter 16 Java Virtual Machine. To compile a java program in Simple.java, enter javac Simple.java javac outputs Simple.class, a file that contains bytecode.
1 Lecture 10 Intermediate Representations. 2 front end »produces an intermediate representation (IR) for the program. optimizer »transforms the code in.
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics C# Language &.NET Platform 12 th -13 th Lecture Pavel Ježek.
1 Compiler Construction Intermediate Code Generation.
Generating Data Access Assemblies with IronRuby Rob Rowe Blog: rob-rowe.blogspot.com.
Intermediate code generation. Code Generation Create linear representation of program Result can be machine code, assembly code, code for an abstract.
3/17/2008Prof. Hilfinger CS 164 Lecture 231 Run-time organization Lecture 23.
Run-time Environment and Program Organization
C# Tutorial From C++ to C#. Some useful links Msdn C# us/library/kx37x362.aspxhttp://msdn.microsoft.com/en- us/library/kx37x362.aspx.
David Evans CS201j: Engineering Software University of Virginia Computer Science Lecture 18: 0xCAFEBABE (Java Byte Codes)
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics C# Language &.NET Platform 7 th & 8 th Lecture Pavel Ježek.
Advanced .NET Programming I 13th Lecture
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics C# 3.0 and.NET 3.5: A Brief Overview Pavel Ježek.
IT253: Computer Organization Lecture 4: Instruction Set Architecture Tonga Institute of Higher Education.
LANGUAGE TRANSLATORS: WEEK 24 TRANSLATION TO ‘INTERMEDIATE’ CODE (overview) Labs this week: Tutorial Exercises on Code Generation.
CSC 310 – Imperative Programming Languages, Spring, 2009 Virtual Machines and Threaded Intermediate Code (instead of PR Chapter 5 on Target Machine Architecture)
ABHISHEK BISWAS.NET Reflection Dynamically Create, Find and Invoke Types.
Hoang Anh Viet Hà Nội University of Technology Chapter 1. Introduction to C# Programming.
Run-Time Storage Organization Compiler Design Lecture (03/23/98) Computer Science Rensselaer Polytechnic.
MSIL C#.NET Software Development. MSIL AKA CIL What all.NET languages compile to What all.NET languages compile to Binary Intermediate Language Binary.
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics Advanced.NET Programming I 10 th Lecture Pavel Ježek
Programming Languages and Paradigms Activation Records in Java.
Compiler Construction Code Generation Activation Records
Wel come To Seminar On C#.
Bruno Cabral “Reflection, Code Generation and Instrumentation in the.NET platform” University of Coimbra.
Intermediate code generation. Code Generation Create linear representation of program Result can be machine code, assembly code, code for an abstract.
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics C# Language &.NET Platform 4 th Lecture Pavel Ježek
A Microsoft.NET Front-End for GCC Bernhard Rabe Martin von Löwis Jan Möller Operating Systems & Middleware Group Hasso-Plattner-Institute, University of.
The Execution System1. 2 Introduction Managed code and managed data qualify code or data that executes in cooperation with the execution engine The execution.
Overview CNS 3260 C#.NET Software Development. 2.NET Framework Began in 2000 Developed in three years (2000 to 2003) Operating System Hardware.NET Framework.
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics C# Language &.NET Platform 7 th Lecture Pavel Ježek
METADATA IN.NET Presented By Sukumar Manduva. INTRODUCTION  What is Metadata ? Metadata is a binary information which contains the complete description.
7-Nov Fall 2001: copyright ©T. Pearce, D. Hutchinson, L. Marshall Oct lecture23-24-hll-interrupts 1 High Level Language vs. Assembly.
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics Advanced.NET Programming I 7 th Lecture Pavel Ježek
CHARLES UNIVERSITY IN PRAGUE faculty of mathematics and physics Advanced.NET Programming II 2 nd Lecture Pavel Ježek
Advanced .NET Programming I 11th Lecture
Assembly language.
MIPS Instruction Set Advantages
Advanced .NET Programming II 6th Lecture
CS216: Program and Data Representation
Advanced .NET Programming I 8th Lecture
Advanced .NET Programming I 4th Lecture
Advanced .NET Programming I 7th Lecture
Optimization Code Optimization ©SoftMoore Consulting.
RISC Concepts, MIPS ISA Logic Design Tutorial 8.
CS41B recursion David Kauchak CS 52 – Fall 2015.
CS360 Windows Programming
Chapter 1 IDE and Tools for Developing CLR-based Programs
Introduction to C# AKEEL AHMED.
.NET and .NET Core 5.2 Type Operations Pan Wuming 2016.
Instructions - Type and Format
CSC 3210 Computer Organization and Programming
Memory Allocation CS 217.
PZ09A - Activation records
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
Advanced .NET Programming I 8th Lecture
Advanced .NET Programming I 5th Lecture
C# Language & .NET Platform 10th Lecture
Advanced .NET Programming I 7th Lecture
Advanced .NET Programming I 4th Lecture
Principles of Computers 16th Lecture
C# Language & .NET Platform 11th Lecture
Advanced .NET Programming I 6th Lecture
C# Language & .NET Platform 3rd Lecture
C# Language & .NET Platform 9th Lecture
C# Language & .NET Platform 4th Lecture
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
C# Language & .NET Platform 12th Lecture
Presentation transcript:

Advanced .NET Programming I 9th Lecture Pavel Ježek pavel.jezek@d3s.mff.cuni.cz Some of the slides are based on University of Linz .NET presentations. © University of Linz, Institute for System Software, 2004 published under the Microsoft Curriculum License (http://www.msdnaa.net/curriculum/license_curriculum.aspx)

Lambda Expressions as Delegates When assigned to a delegate, equivalent code of an anonymous method is generated at compile time! value => (value + 2) * 10 Func<int, int> f = Compile time generation IL_0000: ldarg.0 IL_0001: ldc.i4.2 IL_0002: add IL_0003: ldc.i4.s 10 IL_0005: mul IL_0006: stloc.0 IL_0007: br.s IL_0009 IL_0009: ldloc.0 IL_000a: ret

Lambda Expressions as Expression Trees Permit lambda expressions to be represented as data structures instead of executable code Lambda expression convertible to delegate D (assignment causes code generation) is also convertible to expression tree (abstract syntax tree) of type System.Linq.Expressions.Expression<D> (assignment causes expression tree generation – compile time generation of code, that creates the expression tree [class instances] at runtime) Expression trees are immutable value => (value + 2) * 10 Func<int, int> f = Expression<Func<int, int>> e = Compile time generation Compile time generation IL_0000: ldarg.0 IL_0001: ldc.i4.2 IL_0002: add IL_0003: ldc.i4.s 10 IL_0005: mul IL_0006: stloc.0 IL_0007: br.s IL_0009 IL_0009: ldloc.0 IL_000a: ret new LambdaExpression( new BinaryExpression( ParameterExpression(“value”) ConstantExpression(2) ) ConstantExpression(10)

Expression Trees Classes inheriting from Expression (since .NET 3.5): System.Linq.Expressions.BinaryExpression System.Linq.Expressions.ConditionalExpression System.Linq.Expressions.ConstantExpression System.Linq.Expressions.InvocationExpression System.Linq.Expressions.LambdaExpression System.Linq.Expressions.MemberExpression System.Linq.Expressions.MethodCallExpression System.Linq.Expressions.NewExpression System.Linq.Expressions.NewArrayExpression System.Linq.Expressions.MemberInitExpression System.Linq.Expressions.ListInitExpression System.Linq.Expressions.ParameterExpression System.Linq.Expressions.TypeBinaryExpression System.Linq.Expressions.UnaryExpression New classes inheriting from Expression (since .NET 4.0): System.Linq.Expressions.BlockExpression System.Linq.Expressions.LoopExpression System.Linq.Expressions.TryExpression …

Expression Trees and LINQ

Lambda Expressions as Expression Trees value => (value + 2) * 10 Func<int, int> f = Expression<Func<int, int>> e = Compile time generation Compile time generation IL_0000: ldarg.0 IL_0001: ldc.i4.2 IL_0002: add IL_0003: ldc.i4.s 10 IL_0005: mul IL_0006: stloc.0 IL_0007: br.s IL_0009 IL_0009: ldloc.0 IL_000a: ret new LambdaExpression( new BinaryExpression( ParameterExpression(“value”) ConstantExpression(2) ) ConstantExpression(10) Runtime time generation by JIT machine code (e.g. x86) (code actually executed by real CPU)

Expression Trees to Dynamic Methods (via Implicit Reflection.Emit) Runtime generation of CIL code of a dynamic method from expression tree instance: value => (value + 2) * 10 Func<int, int> f = Expression<Func<int, int>> e = Compile time generation Compile time generation IL_0000: ldarg.0 IL_0001: ldc.i4.2 IL_0002: add IL_0003: ldc.i4.s 10 IL_0005: mul IL_0006: stloc.0 IL_0007: br.s IL_0009 IL_0009: ldloc.0 IL_000a: ret new LambdaExpression( new BinaryExpression( ParameterExpression(“value”) ConstantExpression(2) ) ConstantExpression(10) Runtime time generation f = e.Compile(); Runtime time generation by JIT machine code (e.g. x86) (code actually executed by real CPU)

Expression Trees – Hello world! Dynamically creating an expression tree for () => Console.WriteLine(“Hello world!”) lambda expression: delegate void VoidDelegate(); class Program { static void Main(string[] args) { MethodInfo mi = typeof(Console).GetMethod( "WriteLine", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string) }, null ); Expression<VoidDelegate> expr = Expression.Lambda<VoidDelegate>( Expression.Call(mi, Expression.Constant("Hello world!") ) VoidDelegate d = expr.Compile(); d(); }

Expression Trees – Another Example delegate void Void1Delegate(int value); Console.Write("Enter a number: "); int number = int.Parse(Console.ReadLine()); MethodInfo mi = typeof(Console).GetMethod( "WriteLine", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), typeof(object) }, null ); ParameterExpression param = Expression.Parameter(typeof(int), "valueToAdd"); Expression<Void1Delegate> expr = Expression.Lambda<Void1Delegate>( Expression.Call( mi, Expression.Constant("Hello world! Value is {0}"), Expression.Convert( Expression.Add( param, Expression.Constant(number, typeof(int)) ), typeof(object) ) param Void1Delegate d = expr.Compile(); d(10); d(20);

Implementing Generic Complex, etc. struct IntWrapper { public int v; public IntWrapper(int value) { v = value; } public static IntWrapper operator +(IntWrapper a, IntWrapper b) { return new IntWrapper(a.v + b.v);

Implementing Generic Complex, etc. (a Problem) struct IntWrapper { public int v; public IntWrapper(int value) { v = value; } public static IntWrapper operator +(IntWrapper a, IntWrapper b) { return new IntWrapper(a.v + b.v); Cannot be rewritten to: struct Wrapper<T> { public T v; public Wrapper(T value) { public static Wrapper<T> operator +(Wrapper<T> a, Wrapper<T> b) { return new Wrapper<T>(a.v + b.v);

Implementing Generic Complex, etc. (using ExprTree) using System.Linq.Expressions; struct ValueWrapper<T> { public T v; private static Func<T, T, T> addProxy; static ValueWrapper() { // Creates (a, b) => a + b lambda expression at runtime ParameterExpression paramA = Expression.Parameter(typeof(T), "a"); ParameterExpression paramB = Expression.Parameter(typeof(T), "b"); BinaryExpression addExpr = Expression.Add(paramA, paramB); addProxy = Expression.Lambda<Func<T, T, T>>(addExpr, paramA, paramB).Compile(); } public ValueWrapper(T value) { v = value; public static ValueWrapper<T> operator +(ValueWrapper<T> a, ValueWrapper<T> b) { return new ValueWrapper<T>(addProxy(a.v, b.v));

Implementing Generic Complex, etc. (using ExprTree) using System.Linq.Expressions; struct ValueWrapper<T> { public T v; private static Func<T, T, T> addProxy; static ValueWrapper() { // Creates (a, b) => a + b lambda expression at runtime ParameterExpression paramA = Expression.Parameter(typeof(T), "a"); ParameterExpression paramB = Expression.Parameter(typeof(T), "b"); BinaryExpression addExpr = Expression.Add(paramA, paramB); addProxy = Expression.Lambda<Func<T, T, T>>(addExpr, paramA, paramB).Compile(); } public ValueWrapper(T value) { v = value; public static ValueWrapper<T> operator +(ValueWrapper<T> a, ValueWrapper<T> b) { return new ValueWrapper<T>(addProxy(a.v, b.v));

CIL/MSIL Code

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x Disassembled machine code ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 R2 R1 R0 RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers IP LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x Disassembled machine code ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 R2 R1 2 R0 RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x IP ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 R2 4 R1 2 R0 RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 R2 4 R1 2 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 R2 4 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 R2 1 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 1 R2 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 1 R2 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 1 R2 2 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 $F7 R2 2 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 $F7 R2 2 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 8 R2 2 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 8 R2 2 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 8 R2 16 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 8 R2 16 R1 6 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 8 R2 16 R1 22 R0 IP RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 8 R2 16 R1 22 R0 IP global data: ... ? address x RegStackTop Flags (SP) IP

Stack Machine CPU registers memory Load/store architecture Loads have implicit target (register on top) Stores have implicit source (register on top) Arithmetic instructions have all operands implicit (n-nary operation takes n registers from top) CPU registers LOAD 2 LOAD 4 ADD LOAD 1 LOAD $F7 NOT MUL STORE x ? R15 R14 R13 R12 R11 R10 R9 R8 R7 R6 R5 R4 R3 8 R2 16 R1 22 R0 IP global data: ... 22 address x RegStackTop Flags (SP) IP

CIL/MSIL Code

Conditional Branch/Jump instructionA1 if P then begin instructionT11 instructionT12 instructionT21 end else begin instructionF11 instructionF21 end; instructionA2 if P then JMP x ↓ if P then JMP x else NOP instructionA1 if not(P) then JMP elseBranch; instructionT11 instructionT12 instructionT21 JMP endIf; elseBranch: instructionF11 instructionF21 endIf: instructionA2

CIL/MSIL Code

Reflection.Emit Reflection.Emit allows creation of assemblies and types at run-time creation of assemblies creation of new modules creation of new types creation of symbolic meta-information of existing modules System.Reflection.Emit supports realization of .NET compilers und interpreters Important classes of Reflection.Emit are AssemblyBuilder to define assemblies ModuleBuilder to define modules TypeBuilder to define types MethodBuilder to define methods ILGenerator to emit IL-code Überblick

Example Reflection.Emit (1) Creation of a new assembly and module Definition of a new type Definition of a new method with parameter and return types public class HelloWorld { public virtual string SayHelloTo(string name) { return “Hello “ + name; } AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "HelloWorldAssembly"; AssemblyBuilder newAssembly = Thread.GetDomain().DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder newModule = newAssembly.DefineDynamicModule("HelloWorldModule"); TypeBuilder newType = newModule.DefineType ("HelloWorld", TypeAttributes.Public); Type[] paramTypes = new Type[] { typeof(string) }; Type retType = typeof(string); MethodBuilder newMethod = newType.DefineMethod("SayHelloTo", MethodAttributes.Public | MethodAttributes.Virtual, retType, paramTypes); Überblick

Example Reflection.Emit (2) Defining the MSIL code for the new method Creating the new type Creating an instance of the new type and calling SayHelloTo method ILGenerator ilGen = newMethod.GetILGenerator (); ilGen.Emit (OpCodes.Ldstr, "Hello "); ilGen.Emit (OpCodes.Ldarg_1); Type t = Type.GetType ("System.String"); MethodInfo mi = t.GetMethod ("Concat", new Type[] { typeof(string), typeof(string) }); ilGen.Emit (OpCodes.Call, mi); ilGen.Emit (OpCodes.Ret); newType.CreateType(); Activator: Contains methods to create types of objects locally or remotely, or obtain references to existing remote objects. MethodInfo method = newType.GetMethod ("SayHelloTo", new Type[] {typeof(string)}); object obj = Activator.CreateInstance (newType); object ret = method.Invoke (obj, new object[] { "Jack" }); Console.WriteLine (ret); Hello Jack Überblick

Reflection.Emit -> RegEx

Mono.Cecil