alex turner c# compiler pm session code: dev402 on the dynamic menu today… the dynamic language...
TRANSCRIPT
Dynamic in Microsoft Visual C# 4.0: The Why's and How's Alex Turner
C# Compiler PMSession Code: DEV402
On the Dynamic menu today…
The Dynamic Language RuntimeHow does it relate to the CLR?
Dynamic in C#Why did we design Dynamic the way we did?
DemoLet’s expose dynamic semantics on a type!
What is the CLR?
Common Language Runtime (CLR):Common platform for static languagesStatic binding of operations (at compile-time)Good interop provided byCommon Language Specification (CLS)
What is the DLR?
Dynamic Language Runtime (DLR):Common platform for dynamic languagesDynamic binding of operations (at runtime)Good interop provided by IDynamicMetaObjectProvider protocol (IDMOP)
So, why Dynamic in C#?
After all, C# is not a dynamic language!And never will be
To embrace the dynamic world around us!Use code from dynamic languages such as PythonTalk to dynamic object models like the HTML DOMMore natural interop with COM interfaces
Be a better “citizen of the .NET world”!
PythonBinder
RubyBinder
COMBinder
DOMBinder
ObjectBinder
Dynamic Language Runtime
Dynamic Language RuntimeExpression Trees Dynamic Dispatch Call Site Caching
IronPython IronRuby C# VB.NET Others…
Terminology: Dynamic Binding
Binding: Determining the meaning of an operation based on the type of constituentsStatic binding:Binding is based on compile-time (static) types of expressionsDynamic binding:Binding is based on runtime (actual) types of objects
The Syntax Dilemma
Knee-jerk: It’s got to look different!Type safety first
Secret dream: It’s got to look similar!Beautiful, simple code
Dynamic: A case study
The task:Get an element from a dynamic collection.
Static equivalent: string[] a = GetStringArray(…); string result = a[a.Length – 1];
Syntax Attempt #1
Explicitly dynamic operations:
object d = GetDynamicObject(…);string result = d~[d~.Length - 1];
Syntax Attempt #1
Explicitly dynamic operations:
object d = GetDynamicObject(…);string result = ~(string)d~[d~.Length ~- 1];
Problem: Ugh…
Syntax Attempt #2
Dynamic contexts:
object d = GetDynamicObject(…);string result = dynamic(d[d.Length - 1]);
Syntax Attempt #2
Dynamic contexts:
object d = GetDynamicObject(…);int index = GetIndex(…);string result = dynamic(d[index * 2]);
Syntax Attempt #2
Dynamic contexts:
object d = GetDynamicObject(…);int index = GetIndex(…);string result = dynamic(d[static(index * 2)]);
Problem: Everything is dynamic insideA static context as well to opt out with?Small contexts clutter your expressions
Syntax Attempt #2
Dynamic contexts:
dynamic { object d = static(GetDynamicObject(…)); int index = static(GetIndex(…)); string result = d[static(index * 2)];}
Problem: Everything is dynamic insideA static context as well to opt out with?Small contexts clutter your expressionsLarge block contexts are too blunt an instrument
Syntax Attempt #3
Contagious bit on expressions:
object d = GetDynamicObject(…);int index = GetIndex(…);string result = dynamic(d)[index * 2];
Syntax Attempt #3
Contagious bit on expressions:
object d = GetDynamicObject(…);string result = d[dynamic(d).Length - 1];
Syntax Attempt #3
Contagious bit on expressions:
object d = GetDynamicObject(…);var len = dynamic(d).Length;string result = d[dynamic(len) - 1];
Problem: How do we track “dynamicness”?Can it persist across assignments?C# already has a system for this kind of tracking…
Syntax Attempt #4
Dynamic type:
dynamic d = GetDynamicObject(…);var len = d.Length;string result = d[len - 1];
Syntax Attempt #4
Dynamic type:
dynamic d = GetDynamicObject(…);int index = GetIndex(…);string result = d[index * 2];
Syntax Attempt #4
Dynamic type:
dynamic d = GetDynamicObject(…);string result = d[d.Length - 1];
Pro: There’s no difference!Developer intent is as easy to see as in static code
Con: There’s no difference!No local indication that code is dynamic
Why is this safe?
You only get dynamic dispatch when your expressions have the special type dynamic.
In C# today, you need to figure out an expression’s type to infer what operations on it will do
IntelliSense will keep you on the static path whenever possible
Dynamic takes code that would resolve at runtime anyway and makes it natural to read and write
“Statically typed to be dynamic”
Calculator calc = GetCalculator();int sum = calc.Add(10, 20);
object calc = GetCalculator();Type calcType = calc.GetType();object res = calcType.InvokeMember("Add", BindingFlags.InvokeMethod, null, new object[] { 10, 20 });int sum = Convert.ToInt32(res);
ScriptObject calc = GetCalculator();object res = calc.Invoke("Add", 10, 20);int sum = Convert.ToInt32(res);
dynamic calc = GetCalculator();int sum = calc.Add(10, 20);
Statically typed to be dynamic
Dynamic method invocation
Dynamic conversion
Type or Type Modifier?
Generality:dynamic Foo d = GetDynamicFoo(…);
Static binding of Foo’s membersDynamic binding of the rest
Simplicity:dynamic d = GetDynamicFoo(…);
Dynamic binding of all membersEven those on Object
“The object is king” – we let dynamic objects decide when to fall back to their static members
Dynamic expressions when?
When the receiver is dynamic?What to do when arguments are dynamic?double result = Math.Abs((double)d);
Not calling Math.Abs dynamically forces you to choose a single type
When any constituent expression is dynamic!dynamic result = Math.Abs(d);
Overload chosen at runtime based on the type of d
Result type of dynamic expressions
Dynamic type:Method call Math.Abs(d)Invocation d("Hello")Member access d.LengthOperator application d + 4Indexing d["Hello"]
Static type:Conversions (double)dObject creation new Foo(d)
Runtime binders
C# runtime binder (in Microsoft.CSharp.dll):Handles binding of “ordinary .NET objects”Mimics compile time semantics
IDynamicMetaObjectProvider implementations:Implemented by a given dynamic objectObject handles its own binding
“The object is king”Can choose to fall back to language binder
C# Runtime semanticsdynamic d = GetDynamicObject(…);MathHelper.Power(4, d);
Constituents typed as dynamic:Use their actual runtime type
Statically typed constituents:Use their compile-time static typeUse other static info like literalness
Principle of least surprise:Only as dynamic as we have to be!
Dynamic is useful… and it’s safe!
The dynamic type lets you access dynamic object models by writing simple code that is easy to read and understand!By treating dynamic as a type, we reuse C#’s primary way of piping extra data through your control flow, and keep your static code safe.As a guiding principle: if you miss IntelliSense, you’ve gone too far!Have fun!
For more info on Dynamic…Using C# 4.0 & VB10 Interop Features with Silverlight, Office & Python [DEV03-IS]November 12, 16:15 - 17:30 – Interactive Theatre 2 - Orange Alex Turner
www.microsoft.com/teched
Sessions On-Demand & Community
http://microsoft.com/technet
Resources for IT Professionals
http://microsoft.com/msdn
Resources for Developers
www.microsoft.com/learning
Microsoft Certification & Training Resources
Resources
© 2009 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS,
IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.