alex turner c# compiler pm session code: dev402 on the dynamic menu today… the dynamic language...

36

Upload: daniel-patterson

Post on 31-Dec-2015

213 views

Category:

Documents


0 download

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

Creating Dynamic Objectsdemo

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

question & answer

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

Complete an evaluation on CommNet and enter to win an Xbox 360 Elite!

© 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.