Title: Deep Reflection
1Deep Reflection
noitcelfeR peeD
Cool Hot Reflection 2.03.5 Features
Roy Osherove, Typemock www.ISerializable.com
(blog)
Roy_at_Osherove.com
2Assumption You already know Reflection
3Agenda
- Generate Code
- Reflection.Emit in 3 Minutes
- Easier
- Faster Code
- Debuggable
- Visualizable
- Inspect Code at Runtime
- More Securely
- Inspect methods IL
- 3.5
- Lambdas and compile
- Expression Trees
4Generating Code
5The Cloning/Serializing Problem
- Person
- Name
- Age
- Order
- GUID
- Customer
- Handle any Object Quickly
6The Cloning/Serializing ProblemClassic Reflection
UnknownObject
Gettype().GetMembers()
For Each Member FieldInfo.Copy old value to new
Object
7The Cloning/Serializing ProblemOptimized
UnknownObject
Gettype().GetMemebers()
For Each Member Create Code That Copies
member newObj.Name oldObj.Name
Person ClonePerson(Person) newPerson.Name
old.Name Newperson.Age old.Age
Save as Method for later Invocation
8The Cloning/Serializing ProblemAfter Optimization
UnknownObject
HasCustomMethod?
Person ClonePerson(Person) newPerson.Name
old.Name Newperson.Age old.Age
9Generating Code
Person ClonePerson(Person) newPerson.Name
old.Name Newperson.Age old.Age
10CodeDOM
CodeEntryPointMethod start new
CodeEntryPointMethod() CodeMethodInvokeExpressi
on cs1 new CodeMethodInvokeExpression( new
CodeTypeReferenceExpression("System.Console"),
"WriteLine", new CodePrimitiveExpression("Hello
World!") ) start.Statements.Add(cs1)
Public static void Main() System.Console.WriteL
ine(Hello World!)
11CodeDOM
- CodeArgumentReferenceExpression
- CodeArrayCreateExpression
- CodeArrayIndexerExpression
- CodeAssignStatement
- CodeAttachEventStatement
- CodeAttributeArgument
- CodeAttributeArgumentCollection
- CodeAttributeDeclaration
- CodeAttributeDeclarationCollection
- CodeBaseReferenceExpression
- CodeBinaryOperatorExpression
- CodeCastExpression
- CodeCatchClause
- CodeCatchClauseCollection
- CodeComment
- CodeCommentStatement
- CodeCommentStatementCollection
- CodeCompileUnit
- CodeConditionStatement
- CodeExpressionCollection
- CodeExpressionStatement
- CodeFieldReferenceExpression
- CodeGotoStatement
- CodeIndexerExpression
- CodeIterationStatement
- CodeLabeledStatement
- CodeLinePragma
- CodeMemberEvent
- CodeMemberField
- CodeMemberMethod
- CodeMemberProperty
- CodeMethodInvokeExpression
- CodeMethodReferenceExpression
- CodeMethodReturnStatement
- CodeNamespace
- CodeNamespaceCollection
- CodeNamespaceImport
- CodeNamesapceImportCollection
12More
- CodeCompiler
- CodeDomProvider
- CodeGenerator
- CodeGeneratorOptions
- CodeParser
- CompilerError
- CompilerErrorCollection
- CompilerParameters
- CompilerResults
- Executor
- IndentedTextWriter
- TempFileCollection
- ICodeCompiler
- ICodeGenerator
- ICodeParser
- CodeBinaryOperatorType
- FieldDirection
- CodePropertySetValueReferenceExpression
- CodeRemoveEventStatement
- CodeSnippetCompileUnit
- CodeSnippetExpression
- CodeTypeMemberCollection
- CodeTypeOfExpression
- CodeTypeReference
- CodeTypeReferenceCollection
- CodeTypeReferenceExpression
- CodeVariableDeclarationStatement
- CodeVariableReferenceExpression
13Even More
- CodeEventReferenceExpression
- CodeExpression
- CodeSnippetStatement
- CodeSnippetTypeMember
- CodeStatementCollection
- CodeThisReferenceExpression
- CodeThrowExceptionStatement
- CodeTryCatchFinallyStatement
- CodeTypeConstructor
- CodeTypeDeclaration
- CodeTypeDeclarationCollection
- CodeTypeDelegate
- CodeTypeMember
- CodeCatchClause
- CodeCatchClauseCollection
- CodeComment
- CodeCommentStatement
- CodeCommentStatementCollection
- CodeCompileUnit
- CodeConditionStatement
- CodeConstructor
- CodeDelegateCreateExpression
- CodeDelegateInvokeExpression
- CodeDirectionExpression
- CodeEntryPointMethod
14Generating Code With CodeDOM
15Generating Code With CodeDOM
16(No Transcript)
17The full picture
18CodeDom Half Baked
- Creation of Param Arrays
- Creation of Finalizers
- Static Events
- Readonly fields
- Cant Control String Literals (_at_string)
- Cant Control Order of Implementation
- Partial methods
- Auto properties
- Auto initializers, var, lambdas.
19Agenda
- From CodeDom to Reflection.Emit
20Reflection.Emit
21IL in 3 Minutes
22CLR Internals
- IL The language for execution
- Independent of CPU and platform
- Created by Microsoft, external commercial and
academic language/compiler writers - Stack based virtual machine
10 20 - 5 IL_0001 ldc.i4 10
IL_0002 ldc.i4 20 IL_0003 add
IL_0004 ldc.i4.5 IL_0005 sub
Evaluation Stack
23CLR Internals
- IL The language for execution
- Independent of CPU and platform
- Created by Microsoft, external commercial and
academic language/compiler writers - Stack based virtual machine
10 20 - 5 IL_0001 ldc.i4 10
IL_0002 ldc.i4 20 IL_0003 add
IL_0004 ldc.i4.5 IL_0005 sub
0000 0010
Evaluation Stack
24CLR Internals
- IL The language for execution
- Independent of CPU and platform
- Created by Microsoft, external commercial and
academic language/compiler writers - Stack based virtual machine
10 20 - 5 IL_0001 ldc.i4 10
IL_0002 ldc.i4 20 IL_0003 add
IL_0004 ldc.i4.5 IL_0005 sub
0000 0020
0000 0010
Evaluation Stack
25CLR Internals
- IL The language for execution
- Independent of CPU and platform
- Created by Microsoft, external commercial and
academic language/compiler writers - Stack based virtual machine
10 20 - 5 IL_0001 ldc.i4 10
IL_0002 ldc.i4 20 IL_0003 add
IL_0004 ldc.i4.5 IL_0005 sub
0000 0030
Evaluation Stack
26CLR Internals
- IL The language for execution
- Independent of CPU and platform
- Created by Microsoft, external commercial and
academic language/compiler writers - Stack based virtual machine
10 20 - 5 IL_0001 ldc.i4 10
IL_0002 ldc.i4 20 IL_0003 add
IL_0004 ldc.i4.5 IL_0005 sub
0000 0005
0000 0030
Evaluation Stack
27CLR Internals
- IL The language for execution
- Independent of CPU and platform
- Created by Microsoft, external commercial and
academic language/compiler writers - Stack based virtual machine
10 20 - 5 IL_0001 ldc.i4 10
IL_0002 ldc.i4 20 IL_0003 add
IL_0004 ldc.i4.5 IL_0005 sub
0000 0025
Evaluation Stack
28CLR Internals
- IL storage opcodes
- Locals of a method
- Fields in a class
string a hello world IL_0001 ldstr
hello world IL_0002 stloc a
IL_0003 ldloc a
foo.f hello world IL_0001 ldstr
hello world IL_0002 stfld string
Foof IL_0003 ldfld string Foof
29CLR Internals
if (a) ... else ... IL_0001
ldloc a IL_0002 ldc.i4.1 IL_0003 ceq
IL_0004 brfalse IL_00020 // if true
statements IL_0010 ... IL_0011 br
IL_00025 // else statements IL_0020
... // rest of method IL_0025 ...
30CLR Internals
- System.Reflection.Emit namespace used to generate
code - Builder APIs derive from Reflection
Reflection.Emit APIs needed
C source
public class FooClass public static void
Main () string x hello world!
Console.WriteLine(x)
AssemblyBuilder
ModuleBuilder
TypeBuilder
MethodBuilder
ILGenerator
OpCodes
LocalBuilder
31Classic Reflection.Emit
32Its Easier
33Lightweight Code Gen (LCG)
Reflection.Emit APIs needed
C source
public static void MyMethod () string x
hello world! Console.WriteLine(x)
DynamicMethod
ILGenerator
OpCodes
34DynamicMethod
35Cloning Optimization Skip Visibility Checks
Cloner
PersonBase
PersonWithAge
PersonWithMoreProperties
PersonWithNumber
36Perf Gains with Reflection.Emit
37Reflection.Emit DynamicMethod
- Creates full Assembly, Module and Type
- Stays in memory until AppDomain dies
- Verify correctness PEVerify.exe,
- IL Debugger
- IDE Debugger
- Visualizer
- Create single static method on existing type
- Garbage Collected
- Verify correctness Visualizer
- Can skip visibility checks
38Run-Sharp
39Finding Problems in IL
40LCG Visualizer Demo
41Its Debuggable
42Debugging Generated Code
- Symbol Support
- Set Debuggable(DisableOptimizations) on
Assembly - ISymbolDocumentWriter ?(Module.DefineDocument)
- Gen.MarkSequencePoint(2,1,2,100)
- Local.SetLocalSymInfo
43Debugging Generated Code
44Its More Secure
45Reflection Hackers
MyApp
- Demo
- Reflecting for Plugins
MyPlugins
PluginSDK
46Reflection-Only Context
- Reflect on Type and Assembly for Meta-Data
- Late-Bound Invocation
- Loader Concept
- Special APIs Added
- Invocations are disabled
47Reflection-Only Context
- Assembly asm Assembly.ReflectionOnlyLoad("asm.dl
l") - Type t Type.ReflectionOnlyGetType("MyType",
false, false) - GetRawXXX()
- GetCustomAttributes ? No more
- CustomAttributeData
48ReflectionOnly Demo
49Reflection over MethodBody
- DynamicMethod dm
- Dm.GetMethodBody().GetILAsByteArray())
- MethodInfo mi ..
- Mi.GetMethodBody().GetILAsByteArray()
50Reflection in .NET 3.5
- Lambdas
- .Compile() for code generation
- Expression Trees
- Parse and understand
51Why should I care?
- Concise Syntax Saves typing
- Can generate code
- Can be parsed
- Mathematical Lambda Calculus
- Functional Languages (Python,F..)
- Functions Objects, with statements
- Executable, but also brows-able
52From delegate to Lambda
- Delegate void SomeDelegate(EventsArgs e)
- Object.SomeEvent new SomeDelegate(Amethod)
- String s
- Object.SomeEvent delegate(EventArgs e)
- //work here
- Lambda
- Object.SomeEvent (e) gt //work here
- Shorter
- No need to put parameter types
- can be parsed into an Expression Tree
53Expression Trees
- Use ExpressionltTgt
- Parse Lambdas at runtime
- Compile at runtime (Expression.Compile())
- Use the Expression Tree Debug Visualizer
- VS 2008-Help-Samples-Samples on disk-local
samples folder- - csharpSamples-LinqSamples-ExpressionTreeVisualizer
54Demo Parse and Visualize Trees
55Demo Compile Lambda
56Pre-Song Summary
- Reflection can be overused
- Use Secure reflection
- Optimize when needed - use Code Gen
- Use the visualizers to debug it
- If generating long code add debug symbols
- Powerful art IF you know what youre doing
57Pre-Song Resources
- Joel Pobars Weblog
- http//blogs.msdn.com/joelpob/
- MethodBase Visualizer
- http//tinyurl.com/nac58
- Mdbg
- http//tinyurl.com/3ksg2
- TestDriven.NET
- www.testdriven.net (Debugging and Testing Addin)
- Roys Weblog
- Roy_at_Osherove.com
- ISerializable.com
58I dont want to blog about it
59- It looks like youre doing just fine
60- Its time for a song of mine!
61I dont want to blog about it
- I can tell by your eyes that youve probably
- been coding forever
- And your codes so complex
- That the chance of us fixing it is - never
62- I dont wanna blog about it
- How you made this mess
- I wish you never learned reflection,
- Baby
- I wish reflection in our code
- Was much less.
- Oh yes..
63- I can tell by your code that were
- Going to debug it
- Forever
- There are no unit tests
- Oh man, you must think youre so clever
64- Now its time to
- Talk about it
- Man your code just sucks
- Now your work is full of unreadable Reflection
- You need guidance and direction
- Oh so much
65- Thank you!
- Roy_at_Osherove.com