SlideShare a Scribd company logo
Dynamic Support in .NET 4Basharat Hussain
List the core areas of C# 4.0Developer should focus on:using the dynamic keyword as a data type that supports runtime lookupusing optional parameters for constructors and methodsexplicitly naming an argument being passing to a methodmaking generic interfaces and delegates covariant/contravariantskipping the passing of optional parameters when making calls to COM objectsomitting the ref keyword when calling a method on a COM objectdynamically importing COM APIs and deploying without Primary InteropAssemblies (PIA)working with the enhanced COM Interop features in C# 4.0using the built-in .NET interfaces like IDynamicMetadataObject in .NET 4.0 – to interact with IronRuby/IronPython
Major Theme“ C# 4.0 primarily focus on dynamic programming. "
Dynamic DispatchC#4 now supports dynamic late-binding.Helps communicate with systems not based on .NET Platform2 Approaches to communicate Non .NET systems
Approach 1 – Using Proxyimport the foreign model directly into .NET as a proxy – like COM InteropCOM Interop - using TLBIMP tool  (from C#1)LINQ-to-SQL, contains a tool called SQLMETAL, which imports an existing database into C# proxy classes for use with queries (from C#3)A tool that imports Windows Management Instrumentation (WMI) classes to C#LINQ-to-SQLWCF
Approach 2 – use DynamicForget about type safety at compile timeWe already doing things at runtime in C# 3.5 and laterinvokes a method on a JScriptobjectembed a SQL query in your ADO.NET applicationReflection defer binding to run timeInteropin that case is with .NET itself
Reflection vs. dynamicReflection object o = GetObject();Type t = o.GetType();objectresult = t.InvokeMember("MyMethod", BindingFlags.InvokeMethod, null, o, newobject[] { });inti = Convert.ToInt32(result);Dynamic dynamic o = GetObject();inti = o.MyMethod();
Dynamic KeywordThe dynamic  keyword in C# 4.0Tell compiler – variable type is unknown until runtimedynamic can be thought of as a special version of the type object that is “suspending belief” dynamic is a static type that bypasses static type checkingdynamic d = GetCustomer(); d.FirstName = "foo"; // works as expectedd.Process(); // works as expectedd.MissingMethod(); // No method found!Dynamic declaration meansRuntime sets FirstName propertyRuntime will call Process() methodCompiler is even happy and runtime notice that MissingMethod() is not defined in Customer class Result is exception: RuntimeBinderException 
Dynamic UsabilityNeed to cast between decimal and double decimal foo = GetDecimalValue(); foo = foo / 2.5 ; // Code break because 2.5 typed as doublefoo = Math.Sqrt(foo); // Code break because sqrt expects doublestring bar = foo.ToString("c");Dynamic magic in c#4 – No need to castdynamic foo = GetDecimalValue(); // still returns a decimalfoo = foo / 2.5; // The runtime takes care of this for usfoo = Math.Sqrt(foo); // Again, the DLR works its magicstring bar = foo.ToString("c");
Static vs. Dynamic SwitchingCustomer c = new Customer(); dynamic  d = c; // static to dynamic, easy enoughd.FirstName= "foo"; Customer newCust = d; // Works because d is a CustomerPerson p = d; // works because Customer inherits from PersonSalesRep s = d; // throws RuntimeBinderException exceptionNote: In the example above, no matter how many different ways we reference it, we only have one Customer object (c).
RuntimeBinderExceptiontry{dynamic d = "this is a string";d.Foo();}catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException e){Console.WriteLine(e.Message);}Output:'string' does not contain a definition for 'Foo'
AssignmentAny object can be implicitly converted to dynamicConversely, there is an “assignment conversion” from dynamic to any other type, provided normal implicit conversion in assignment is allowed – again at runtimedynamic d= GetCustomer(); string first = d.FirstName; // assignmentconversiondynamic id = d.CustomerId; // no conversionobject last = d.LastName; // assignmentconversiondynamic d = 10; //Rule: Dynamic is like object so boxing must happen for value types (explained next slides)
The following example throws a RuntimeBinderException because an int is not implicitly convertible to a short:     int i = 7;     dynamic d = i;     short j = d;                // throws RuntimeBinderException
Dynamic bindingThe result of any dynamic operation is itself of type dynamicThe process of selecting which operation to apply based on the types of constituent expressions is referred to as binding.Binding OperationsMember access: d.MMethod invocation: d.M(d1,…,dn)Delegate invocaton: d(d1,…,dn)Element access: d[d1,…,dn]Constructor calls: new C(d1,…,dn)Overloaded unary operators: +, -, !, ~, ++, --, true, falseOverloaded binary operators: +, -, *, /, %, &, &&, |, ||, ??, ^, <<, >>, ==,!=, >, <, >=, <=Compound assignment operators: +=, -=, etc.Implicit and explicit conversions
PossibilitiesdynamicGetDynamicObject(){returnnewobject();}void Demo(){var d = GetDynamicObject(); // getting as return type d.M(7); // calling methodsd.f = d.P; // getting/settings fields and properties    d[“one”] = d[“two”]; // getting/setting through indexersint i = d + 3; // calling operatorsstring s = d(5,7); // invoking as a delegate}
Dynamic reusabilityPossible but not recommendedDynamic can reuse a variable for different types of datadynamic foo = 1234567890;System.Console.WriteLine(foo);foo = "John Charles";System.Console.WriteLine(foo);foo = true;System.Console.WriteLine(foo);
Dynamic dispatch - by Exampledynamic list = GetDynamicList();dynamicindex1 = GetIndex1();dynamicindex2 = GetIndex2();strings = list[++index1, index2 + 10].Foo();Fivedynamic operations in one line First, there’s the dynamic pre-increment on index1, then the dynamic add with index2. Then a dynamic indexer get is called on list. The product of those operations calls the member Foo. Finally, the total result of the expression is converted to a string and stored in s. That’s five dynamic operations in one line, each dispatched at run time.
Dynamic Vs. Object (similarities)Type inference algorithms as described in §7.4 will prefer dynamic over object if both are candidatesThere is an implicit identity conversion between object and dynamicThere is an implicit identity conversion between constructed types that differ only by dynamic versus objectMethod signatures that differ only by dynamic versus object are considered the same and can be overriddenLike with object, there is an implicitconversion from every type (other than pointer types) to dynamic and an explicit conversion from dynamic to every such type.
Dynamic vs. Object (similarities)Type dynamic does not have a separate runtime representation from objecttypeof(dynamic) == typeof(object)is trueThis principle extends to constructed types and array typestypeof(List<dynamic>) == typeof(List<object>)typeof(dynamic[]) == typeof(object[])
Dynamic vs. object (similarities) This statement is correctList<dynamic> dList = new List<object>();You can override Equals method that take object parameter – with dynamicclass Employee{  	public override bool Equals(dynamic obj) { /* ... */ } } Use dynamic as real type argument or, as a return value – even across assembliespublic dynamic GetDynamicThing()
Dynamic vs. object (differences) -Boxing Unboxing 	Object o = 123;             // OK, Implicit cast from Int32 to Object (boxing)Int32 n1 = o;                // Error: No implicit cast from Object to Int32Int32 n2 = (Int32) o;     // OK: Explicit cast from Object to Int32 (unboxing)dynamic d = 123;          // OK: Implicit cast from Int32 to dynamic (boxing)Int32 n3 = d;                //OK: Implicit cast from dynamic to Int32 (unboxing)
Dynamic vs. object (differences) - dynamic parameter != object –treat dynamic like actual typesclassMyType{publicvoid Method(int x, int y) { Console.WriteLine("Int function"); }publicvoid Method(string s, string t) { Console.WriteLine("Str function"); }publicvoid Method(object o, object p) { Console.WriteLine(“Obj function"); }}classProgram{staticvoid Main(string[] args)    {dynamic d = newMyType();d.Method(10, 20); // Calls the int version.d.Method("abc", "def"); // Calls the string version.  d.Method((object)10, (object)20); // Calls the object version.d.Method((object)"abc", (object)"def"); // Calls the object version.// *d.Method((dynamic)10, (dynamic)20); // Calls the int version. (PHANTOM)d.Method((dynamic)"abc", (dynamic)"def"); // Calls the string version.(PHANTOM)// Repeat of the last 4 cases.d.Method(GetInt(), GetInt()); // Calls the object version.d.Method(GetString(), GetString()); // Calls the object version.d.Method(GetDynamicInt(), GetDynamicInt()); // Calls the int version.    }    staticobjectGetString()    {return ("abc");    }staticobjectGetInt()    {return (5);    }staticdynamicGetDynamicInt()    {return (5);    }}
The result of any dynamic operation is itself of type dynamic, with two exceptions:The type of a dynamic constructor call is the constructed typeThe type of a dynamic implicit or explicit conversion is the target type of the conversion.dynamicis very slow– so use only when necessary otherwise use var.
Implicitly Typed Local Variables and ArraysKeyword var - type is inferred by the compiler from the expression on the right side of the initialization statement.Inference type supportBuilt-in typeAnonymous type (will be discussed later)User-defined typeType defined in the .NET Framework class library
Var - Usagevarivar = 6 // compiled as an intvarsvar="Mony"; // compiled as a stringvariarr_var=new[] {0,1,2 }; // compiled as int[] - arrayvarsarr_var=new[] {"hello",null,"world" }; // string[]a// query is compiled as IEnumerablevarquery = from c in customerswhere c.Name =="Mony"select c;// anonymous_variable is compiled as an anonymous typevaranonymous_variable =new { Name = “Sami", Job = "Web Developer" };var list =new List();
VarRestrictionsIs always local to a method and first time initializationCannot be nullCannot be used as class’s fieldCannot be uses in initialization again with variablevar i = i++;  - compile-time errorMultiple implicitly-typed variables cannot be initialized in the same statement.
DLR ArchitectureThe DLR Runs on Top of the CLR
DLR ServicesDLR adds three services to the CLR for better supporting dynamic languagesExpression TreesThe same expression trees used in LINQ, now improved to support statements ( language syntaxes and semantics).Call Site CachingFor improved efficiency.Dynamic DispatchDispatches invocations to the appropriate binder.Dynamic Object Interoperability These are essentially a set of interfaces that help creation of dynamic objects.
Expression treesThe same expression trees used in LINQ, now improved for DLR to support statements ( language syntaxes and semantics).DLR has extended LINQ expression trees to include control flow, assignment, and other language-modeling nodes
Call site cachingA dynamic call site is a place in the code where you perform an operation like a + b or a.b on dynamic objects. DLR Cache usage/ characteristics of dynamic objects a and b. If such operation performed previously, the DLR retrieves all the necessary information from the cache for fast dispatchAlso cache  information about operations on the ‘Dynamic Objects’
Dynamic dispatchWikipedia says:“Dynamic dispatch (dynamic binding) is the process of mapping a message to a specific sequence of code (method) at runtime. This is done to support the cases where the appropriate method cannot be determined at compile-time (i.e. statically)”.Binders are used by DLR
Dynamic dispatch – underneth bindersUnderneath the DLR there are binders that talk to a variety of different technologies:.NET BinderAllows to talk to .NET objects.JavaScript BinderAllows to talk to JavaScript in SilverLight.IronPython BinderAllows to talk to IronPython.IronRuby BinderAllows to talk to IronRuby.COM BinderAllows to talk to COM.OtherwiseThrow Exception: RuntimeBinderException
Dynamic dispatch mechanismRuntime resolution is based on nature of dynamic variableCache Info: Use call site cahe information, if operation on object is previously performedCOM objectsCOM Interopscenarios - Calling through IUnknown and IDispatch interfaces of COMOffice automationDynamic objectsConsuming types written in dynamic languages as IronPython and IronRuby to implement their own dynamic object modelsHTML DOM to allow direct access to the object’s propertiesimplements the interface IDynamicObjectIDynamicMetaObjectProviderPlain objectsUsing reflection against an underlying CLR type
Dynamic dispatch - by Exampledynamic d1 = new Foo();dynamic d2 = new Bar();string s;d1.M(s, d2, 3, null);“Perform an instance method call of M with the following arguments:a string a dynamic a literal int 3a literal object null”Resolution Sequence At Runtime: assume that the actual type Foo of d1 is not a COM type And it does not implement IDynamicObjectIDynamicMetaObjectProviderThen proceed following wayUse Reflection and get actual runtime types of the two objects, d1 and d2, >> Foo for d1 and Bar for d2.Method lookup and overload resolution is performed for Foo.M(string,Bar,3,null)If found – inoke itOtherwise throw RuntimeBinderException
COM automation interop – dynamicCode in C#3Type myType = Type.GetTypeFromProgID("IMyLib.MyClass"); object obj = Activator.CreateInstance(myType); object[] args = new object[2]; args[0] = "Hello"; args[1] = 3; myType.InvokeMember("MyMethod", BindingFlags.InvokeMethod, null, args);New Code in C#4================Type myType = Type.GetTypeFromProgID("IMyLib.MyClass"); dynamic { object obj = Activator.CreateInstance(myType); obj.MyMethod("Hello", 3); }
Limitations of Dynamic LookupExtension methods - not supportedDynamic lookup will not be able to find extension methods. Whether extension methods apply or not depends on the static context of the call.Anonymous functions as parameters - not  supportedAnonymous functions (i.e. lambda expressions) cannot appear as arguments to a dynamic method call. The compiler cannot bind (i.e. “understand”) an anonymous function without knowing what type it is converted to
Limitation Exampledynamic collection = …;var result = collection.Select(e => e + 5);Select method is an extension method to collection, dynamic lookup will not find it.object collection = context.Students.Select( s=>	new { Id = s.Id, Name = s.Name}).ToList();dynamic d = collection;int count = d.Count;Because collection is anonymous type so dynamic cannot understand it.
The Visitor Pattern and dynamic in C# 4http://code.logos.com/blog/2010/03/the_visitor_pattern_and_dynamic_in_c_4.htmlDynamic can even avoid Visitor Pattern in some casespublicclassMySpecialFunctions{ publicvoid Execute(int x) {...}   publicvoid Execute(string x) {...}   publicvoid Execute(long x) {...} }With Multi-dispatch casedynamic x = getx(); varmyFunc = newMySpecialFunctions(); myFunc.Execute(x);
IDynamicMetaObjectProvider
IDynamicMetaObjectProviderTells the DLR, "I know how to dispatch operations on myself.“This interface contains single method:DynamicMetaObjectGetMetaObject (Expression parameter)Blog Examplehttp://blogs.msdn.com/b/cburrows/archive/2008/10/28/c-dynamic-part-ii.aspx
Framework implementationsThe .NET Framework already provides two implementations of IDynamicMetaObjectProvider:ExpandoObject: IDynamicMetaObjectProviderDynamicObject: IDynamicMetaObjectProvider
ExpandoObject Expandosare expandable objects which means you can add properties, methods and even events at runtime. You can also set and get the values of such members.Can also pass Expando objects as parameters to other methodsLimitation: Will not get intellisense on the dynamic object because they are resolved at runtimeMSDN Example: http://msdn.microsoft.com/library/system.dynamic.expandoobject.aspx
Example – Expando Objectusing System;usingSystem.Dynamic;namespaceDLRExample{classProgram    {staticvoid Main(string[] args)        {dynamic Vehicle = newExpandoObject();Vehicle.Make = "Cultus";Vehicle.Model = "2008";Vehicle.Engine = "4 cylinder";Vehicle.Color = "Silver";WriteVehicleDetails(Vehicle);Console.ReadLine();        }staticvoidWriteVehicleDetails(dynamicvehicleobject)        {Console.WriteLine("The make of the vehicle is {0}", vehicleobject.Make);Console.WriteLine("The color of the vehicle is {0}", vehicleobject.Color);        }    }}
ExpandoObject – CONT…Can add methods at runtime - using lambda expressions. Example: add method ChangeVehicleColor() to ExpandoObject - that changes color of the vehicle to whitedynamic Vehicle = newExpandoObject();Vehicle.Make = "Ford";Vehicle.Model = "Endeavour";Vehicle.Engine = "4 cylinder";Vehicle.Color = "Black";Vehicle.ChangeVehicleColor = (Action)(() => {Vehicle.Color="White";});WriteVehicleDetails(Vehicle);Vehicle.ChangeVehicleColor();WriteVehicleDetails(Vehicle);
ExpandoObject – CONT…expando object also implements the generic IDictionaryinterfaceSo you can enumerate the members of the object, if need.dynamic vehicle = newExpandoObject();vehicle.Make = "Cultus";vehicle.Model = "2008";vehicle.Engine = "4 cylinder";vehicle.Color = "Silver";EnumerateMembers(vehicle);=============================staticvoidEnumerateMembers(dynamicvehicleObject){foreach (var property in (IDictionary<String, Object>)vehicleObject)    {Console.WriteLine(property.Key + ": " + property.Value);    }}
DynamicObjectProvides a base class for specifying dynamic behavior at run time. This class must be inherited from; User cannot instantiate DynamicObjectdirectly while ExpandoObject can.The DynamicObject class - define which operations can be performed on dynamic objects and howto perform those operationsMSDN Example: http://msdn.microsoft.com/library/system.dynamic.dynamicobject.aspxInterstingOppertunity: Receiver Object have an opportunity to inject it self into binding at runtimeSo Object can determine the semantics of any dynamic operation (like dynamic method call) –TryInvokeMemberknows how to handle it?
My Dynamic Object ImplementationCaller Codedynamic d = newMyDynamicObject(); d.Bar("Baz", 3, d);So the call to Bar Compiler don’t know anything at compile timeRun time, the object itself is asked what to do with this call to Bar. That’s what TryInvokeMember knows how to handle.Definition of My Dynamic classclassMyDynamicObject : DynamicObject{publicoverrideboolTryInvokeMember(InvokeMemberBinder binder, object[] args, outobject result)    {Console.WriteLine("Method: {0}", binder.Name);foreach (var arg in args)        {Console.WriteLine("Argument: {0}", arg);        }result = args[0];returntrue;    }}Output of this code is:Method: Bar Argument: BazArgument: 3 Argument: MyDynamicObject
UsageThe Expando object is interoperable between different framework languages. So it is an obvious choice in situations where you have to pass objects between different framework languages that support the DLR interoperability model (IronPython, IronRuby).The Dynamic object is a good choice for interacting with COM interops. Useful to also be used with scripting objects (HTML DOM from Sliverlight).If these two objects don’t do the trick for you, remember you can always create your own dynamic objects by implementing the IDynamicMetaObjectProviderinterface.
BLOGS	http://blogs.msdn.com/b/samng/archive/tags/dynamic/http://blogs.msdn.com/b/cburrows/archive/tags/dynamic/
The Phantom MethodRule of thumb:Everything is convertible to dynamic – Implicit ConversionDynamic is not convertible to anything – Explicit Conversion or Assignment Conversion
phantom methodpublicclassC{publicvoid Foo(int x) { }staticvoid Main()    {dynamic d = 10;Cc = newC();c.Foo(d);    }}c.Foo(d) call contain dynamic, where assignment conversion is needed. Foo(int) is not suffucent. Foo(dynamic) overload is needed
phantom methodIn each of these special situations compiler generates all the surrounding DLR code that prompts a runtime conversion.The special situations in question are the following:Overload resolution - c.Foo(d)Assignment conversion - C c = dConditionals - if (d)Using clauses - using (dynamic d = ...)Foreach - foreach (var c in d)Where c is static while d dynamic variable
Overload resolution – phantom methodSince dynamic (d) is not convertible to anything (int), however, since we've got a dynamically typed argument, we really want the overload resolution for this call to be bound dynamically. Enter the phantom method.The phantom method is a (overload) method which is introduced into the candidate set that has the same number of parameters as the number of arguments given, and each of those parameters is typed dynamic.C.Foo(d) will bind to this Phantommethod Foo(dynamic), not Foo(int).
phantom methodIf compiler detects C.Foo(d) taking dynamic as parameterIt genertaes two overloads: Foo(int) and Foo(dynamic). The first overload fails because dynamic is not convertible to int. The second, the phantom, succeeds and so we bind to it.Once a call is bound to the phantom overload, the compiler knows to generate the correct DLR magic to signal dispatching the call at runtime.Question remains: when does the phantom overload not generated?
phantom methodThe phantom will be introduced if:All of the non-dynamic arguments are convertible to their respective parameters.At least one of the dynamic arguments is not convertible to its respective parameter. It would be possible for a call containing a dynamic argument to be dispatched statically instead of dynamically
phantom methodpublicclassC{publicvoid Foo(int x, dynamic y) { ... }staticvoid Main()    {Cc = newC();dynamic d = 10;c.Foo(10, d);    }}No phantom overload created in candidate setinitial binding pass and overload resolution behave like normal - despite the occurrence of a dynamic parameter
Advanced Dynamic Limitations
Mutating values Types using dynamicdynamicd = 10;d++;Console.WriteLine(d); //d=11If right side is value type then dynamic behave like and object and boxing takes place.Variable d contains boxed copy of integer valueAt runtime, ++ operator on d means unbox first into integer, then increment unboxed value, but value is not copied back inside box. Problem … because .Net/CLR have no ability on ref returns Solution: There is an expression tree that performs an unbox and modifies the boxed value, and puts that value back into the box, allowing you to mutate the boxed values of these things.
Nested structmutationExtending last issue on value type, if any of the dotted expressions were to bind to a value type, that value will be boxed (and hence a copy would be made), and further dots into it would be made on the copy of the value, and not the initial value as would be expected. Introduced bug in following example
Nested structmutation - ExamplepublicstructS{publicint i;} publicclassD{publicSs;publicvoid Execute()    {dynamic d = newD();d.s = default(S);d.s.i = 10;Console.WriteLine(d.s.i);    }}d.s.i will print 0 ???
Base callsThere is a restriction in the CLR that prevents the compiler from generating non-virtual calls on virtual methods. This means that there is no way to call a base overload dynamically. This means that one cannot call a base call with any dynamically typed arguments, as it will trigger a dynamic binding.
Explicitly implemented interface methods not supportedInterfaces are really compile time constructs, and have no runtime representation, explicitly implemented interface members get lost.interfaceIFoo{void M();}classC : IFoo{voidIFoo.M() { }}C.M() is never callable from dynamic.
No phantom for privateThe down side of this scenario is that you could make a call with a static receiver to a private method that you know you can access from your context, but because a dynamic argument is given, the runtime binder will prevent you from calling the method.publicclassC{privatevoid M(int x) { }staticvoid Main()    {dynamic d = 10;Cc = newC();c.M(d);    }}Complier will succeed because c.M() is accessiblein Main. Since argument is dynamic, call is resolved at runtime, Runtime binder have public only policy, so it will not generate Phantom overload with signature M(dynamic). So overload resolution will not bind to the method
More interesting scenarios
Static or dynamic?publicclassC{staticvoid Main()    {Cc = newC();dynamic d = 10;c.Foo(d, 10); // (1)   Static Operationd.Foo(10, 10); // (2)  Dynamic Operation    }publicvoid Foo<T, S>(T x, S y) { }}The first call is a statically known receiver with a dynamically typed argument. The second is a dynamically typed receiver with a statically known argument.
Compiler ignores type inference of parameter type (and constraints)Compiler assumes it is convertible at compile time, so skipping type inference may result unexpected resultspublicclassC{staticvoid Main()    {Cc = newC();dynamic d = 10;c.Foo(10, d);    }publicvoid Foo<T>(T t, int x) where T : class { }}Compiler currently allow this call to compile successfully and fail at runtime!Bug in Type Inference algorithm
A complex scenariopublicinterfaceIAnimal { }publicinterfaceIWatcher<in T> { }       //Contravariant in TpublicclassWatcher<T> : IWatcher<T> { }publicclassC{staticvoid Main(string[] args)    {Cc = newC();IWatcher<Giraffe> a = newWatcher<Giraffe>();IWatcher<Monkey> b = newWatcher<Monkey>();dynamic d1 = 10;dynamic d2 = newWatcher<Mammal>();IWatcher<dynamic> d3 = newWatcher<dynamic>();c.Bar(a, b, d1); // (1)c.Bar(a, b, d2); // (2)c.Bar(a, b, d3); // (3)    }publicvoid Bar<T>(IWatcher<T> w1, IWatcher<T> w3, IWatcher<T> w2) where T : IAnimal { }}publicclassMammal : IAnimal { }publicclassGiraffe : Mammal { }publicclassMonkey : Mammal { }
Analysis of ExampleIn the first call, this is all fine and good - runtime type inference would also fail on the call. Even 10 is not Ianimal – but belief is suspended for dynamic.However, the second call will succeed at runtime! Because the runtime type of d2 is Watcher<Mammal>, Mammal is added to the candidate set. And because IWatcher is covariant on T, choosing T to be Mammal satisfies argument convertibility for each of the three argumentsThe third call will fail at compile time, because the candidate set for T is {Giraffe, Monkey, dynamic}, and T is not marked inconclusive. Type inference will infer T to be dynamic, since it is the common base class and IWatcher is covariant. However, constraint checking will fail, since dynamic is not an IAnimal.
Language InteroperabilityCalling from/to .NET  the dynamic objects written in IronPythonIronRuby
IronPython Installationhttp://ironpython.net/http://ironpython.codeplex.com/releases/view/54498Iron Python V2.7 - download and install Open-source implementation of the Python programming language which is tightly integrated with the .NET Framework.DLLs path is C:\Program Files\IronPython 2.7IronPython.dllIronPython.Modules.dllMicrosoft.Scripting.dllMicrosoft.Scripting.Core.dll
Invoke IronPython from C#Instantiating the IronPython object from C#4 - using dynamicSteps:Ensure IronPython installedCreate simple console applicationReference DLLs from installed directoryWrite hello.py scriptUse dynamic to create and call IronPython methodHello.pyclass Hello:def __init__(self):        passdef add(self, x, y):        return (x+y)
Invoke IronPythonfrom C#var runtime = Python.CreateRuntime();var scope = runtime.ExecuteFile(@"..\..\scripts\hello.py");var ops = runtime.Operations;varpythonType = scope.GetVariable("Hello");dynamic instance = ops.CreateInstance(pythonType);var value = instance.add(10, 20); //Result = 30Console.WriteLine(value);
Invoke C# “Dynamic Object” from C#/IronPythonpublicclassMyDynamicObject : DynamicObject    {publicvoid Foo()        {Console.WriteLine("Foo() Called");        }publicoverrideDynamicMetaObjectGetMetaObject(System.Linq.Expressions.Expression parameter)        {Console.WriteLine("GetMetaObject() Called");returnbase.GetMetaObject(parameter);        }publicoverrideboolTryInvokeMember(InvokeMemberBinder binder, object[] args, outobject result)        {Console.WriteLine("TryInvokeMember() Called");returnbase.TryInvokeMember(binder, args, out result);        }publicoverrideboolTryGetMember(GetMemberBinder binder, outobject result)        {Console.WriteLine("TryGetMember() Called");returnbase.TryGetMember(binder, out result);        }}(Cont.….)
Invoke C# “Dynamic Object” from C#/IronPythonpublicstaticvoid Execute(){    dynamic myDynamicObject = newMyDynamicObject();//first tey calling this object from C#, it should call Foo() and they try to call MissingMethod();Console.WriteLine("C# Test...");try    {myDynamicObject.Foo();myDynamicObject.MissingMethod();    }catch (Exception ex)    {Console.WriteLine("Got C# exception: " + ex.Message);    }ScriptEnginepythonEngine = Python.CreateEngine();ScriptScopescriptScope = pythonEngine.CreateScope();stringpythonScript = SetPythonScript();ScriptSource script = pythonEngine.CreateScriptSourceFromString(pythonScript, SourceCodeKind.Statements);scriptScope.SetVariable("myDynamicObject", myDynamicObject);//Now do the same thing from python, I expect to get the same behaviour as from C#  Console.WriteLine("\r\nScript Test...");try    {script.Execute(scriptScope);    }catch (Exception ex)    {Console.WriteLine("Got script exception: " + ex.Message);    }}staticstringSetPythonScript(){string s = "";    s += "import clr" + "\r\n";    s += "clr.AddReference('mscorlib')" + "\r\n";    s += "myDynamicObject.Foo();" + "\r\n";    s += "myDynamicObject.MissingMethod();" + "\r\n";return s;}
IronRuby Installationhttp://www.ironruby.net/http://ironruby.codeplex.com/releases/view/25901Iron Ruby V1.0 - download and install Open-source implementation of the Ruby programming language which is tightly integrated with the .NET Framework.DLLs path is C:\Program Files (x86)\IronRuby 1.0v4\binIronRuby.dllIronRuby.Libraries.dllIronRuby.Libraries.Yaml.dllMicrosoft.Dynamic.dllMicrosoft.Scripting.Debugging.dllMicrosoft.Scripting.dllMicrosoft.Scripting.Silverlight.dllSystem.Numerics.dll
Problem with Framework DesignersDynamic Lacks documentationLack compile-time type checkingLack PerformanceLosing IntelliSense
Lacks documentationSevere lack of documentation. The entire application's architecture exists in the mind of the person (or persons) who wrote it. At least with strong-typing, you can go see what the object does via its class definition. With dynamic-typing, you must infer the meaning from it's use, at best. At worst, you have NO IDEA what the object is. It's like programming everything in JavaScript
Lack compile-time type checking>>Dynamic Versionpublicdynamic Foo(dynamic other){dynamic clone = other.Clone();clone.AssignData(this.Data);return clone;}>>Typed Versionpublic T Foo<T>(T other) where T : ICloneable, IAssignData{    T clone = (T)other.Clone();clone.AssignData(this.Data);return clone;} Critic: First one has no static type info, no compile time checking, it's not self documenting, no type inference so people will be forced to use a dynamic reference at the call site to store the result, leading to more type loss
Don’t Use BlindlyAnswer: Use dynamic-only-when-necessary and var-at-all-other-timesPurpose of dynamic includeinteroperability with dynamic languages and platforms such as COM/C++ and DLR/IronPython/IronRubyturning C# itself implementing IDynamicObject
Very Bad PerformanceIf dynamicusage can be avoided, it should be avoided.Statistical performance studydynamic c = 10; int b = c * c; Above code is nice and very easy to read but very slow.Comparisons:Using regular reflection, you can't use defined operators. About 10,000 times slower than a regular multiplication About 100 times slower than an ICalculatorinterface with a Multiply methodUseful Link: http://blogs.msdn.com/b/lucabol/archive/2009/02/05/simulating-inumeric-with-dynamic-in-c-4-0.aspx
Generated Code – for interested onesdynamic c = 10; int b = c * c; 
HTML DOMIf you write Silverlight applications, you might have the need today or in the future to access the HTML DOM containing your Silverlight control. C# dynamic programming makes this task easier.
HTML DOMExpects Dynamic Dispatch from JScriptJScript:var loc = new VELatLong(latitude, longitude);var pin = map.AddPushpin(loc);pin.SetTitle(title);pin.SetDescription(description);map.SetCenterAndZoom(loc, 7);C# 3.0 (Silverlight):ScriptObject loc = win.CreateInstance( "VELatLong", lat, long)ScriptObject pin = (ScriptObject)map.Invoke("AddPushpin", loc);pin.Invoke("SetTitle", title);pin.Invoke("SetDescription", description);map.Invoke("SetCenterAndZoom", loc, 7);dynamic loc = win.New.VELatLong(latitude, longitude)var pin = map.AddPushpin(loc);pin.SetTitle(title);pin.SetDescription(description);map.SetCenterAndZoom(loc, 7);C# 4.0 (Silverlight):
Runtime semantics/sequence of dynamic bindingIf the receiver is a dynamic object – i.e., implements IDynamicMetaObjectProvider– the object itself programmatically defines the resolution of the operations performed on it.
Otherwise the operation gets resolved at runtime in the same way as it would have at compile time, using the runtime type of any constituent value statically typed as dynamic and the compile time type of any other constituent value.
If a constituent value derives from a literal, the dynamic binding is able to take that into account. For instance, some conversions are available only on literals.
If a constituent value of static type dynamic has the runtime value null, it will be treated as if the literal null was used.
Extension method invocations will not be considered – the set of available extension methods at the site of the call is not preserved for the runtime binding to use.

More Related Content

PPTX
Cs1123 4 variables_constants
PPTX
Chapter 7:Understanding Class Inheritance
PPT
C++ polymorphism
PPT
JavaScript - Programming Languages course
PPTX
Chapter 4:Object-Oriented Basic Concepts
PPT
Type Casting in C++
PPSX
DIWE - Advanced PHP Concepts
PPT
Generic Types in Java (for ArtClub @ArtBrains Software)
Cs1123 4 variables_constants
Chapter 7:Understanding Class Inheritance
C++ polymorphism
JavaScript - Programming Languages course
Chapter 4:Object-Oriented Basic Concepts
Type Casting in C++
DIWE - Advanced PHP Concepts
Generic Types in Java (for ArtClub @ArtBrains Software)

What's hot (19)

PPTX
#OOP_D_ITS - 4th - C++ Oop And Class Structure
PDF
Web application architecture
PDF
Java concepts and questions
PPSX
Esoft Metro Campus - Programming with C++
PPTX
C sharp part 001
PPTX
Polymorphism Using C++
PPTX
POLITEKNIK MALAYSIA
ODP
Ppt of c vs c#
PDF
Reflection in Go
PPT
Csharp4 operators and_casts
PPTX
Qcon2011 functions rockpresentation_scala
PPTX
C_plus_plus
PDF
Regular types in C++
PPTX
Oop2011 actor presentation_stal
PPTX
chap4 : Converting and Casting (scjp/ocjp)
DOCX
Computer programming questions
PPTX
C Language (All Concept)
PDF
C notes.pdf
#OOP_D_ITS - 4th - C++ Oop And Class Structure
Web application architecture
Java concepts and questions
Esoft Metro Campus - Programming with C++
C sharp part 001
Polymorphism Using C++
POLITEKNIK MALAYSIA
Ppt of c vs c#
Reflection in Go
Csharp4 operators and_casts
Qcon2011 functions rockpresentation_scala
C_plus_plus
Regular types in C++
Oop2011 actor presentation_stal
chap4 : Converting and Casting (scjp/ocjp)
Computer programming questions
C Language (All Concept)
C notes.pdf
Ad

Similar to 2.dynamic (20)

PPSX
Introduction to c sharp 4.0 and dynamic
PPTX
Whats New In C# 4 0 - NetPonto
PPTX
PDC Video on C# 4.0 Futures
PPTX
OOC MODULE1.pptx
PDF
Functions in C++
PPSX
Object oriented concepts & programming (2620003)
PDF
C++ Object oriented concepts & programming
PDF
Functions in C++.pdf
PPT
Virtual Function and Polymorphism.ppt
PPTX
Object Oriented Programming with C++
PPT
devLink - What's New in C# 4?
PPT
pointers, virtual functions and polymorphisms in c++ || in cpp
PPTX
C concepts and programming examples for beginners
PPTX
Notes(1).pptx
DOCX
C questions
PPTX
ppl unit 3.pptx ppl unit 3 usefull can understood
PPTX
Virtual function
PPT
Generalized Functors - Realizing Command Design Pattern in C++
PDF
22 scheme OOPs with C++ BCS306B_module2.pdfmodule2.pdf
PPTX
Dynamic Language Performance
Introduction to c sharp 4.0 and dynamic
Whats New In C# 4 0 - NetPonto
PDC Video on C# 4.0 Futures
OOC MODULE1.pptx
Functions in C++
Object oriented concepts & programming (2620003)
C++ Object oriented concepts & programming
Functions in C++.pdf
Virtual Function and Polymorphism.ppt
Object Oriented Programming with C++
devLink - What's New in C# 4?
pointers, virtual functions and polymorphisms in c++ || in cpp
C concepts and programming examples for beginners
Notes(1).pptx
C questions
ppl unit 3.pptx ppl unit 3 usefull can understood
Virtual function
Generalized Functors - Realizing Command Design Pattern in C++
22 scheme OOPs with C++ BCS306B_module2.pdfmodule2.pdf
Dynamic Language Performance
Ad

Recently uploaded (20)

PDF
GENETICS IN BIOLOGY IN SECONDARY LEVEL FORM 3
PDF
Weekly quiz Compilation Jan -July 25.pdf
PDF
A systematic review of self-coping strategies used by university students to ...
PPTX
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
PDF
01-Introduction-to-Information-Management.pdf
PDF
2.FourierTransform-ShortQuestionswithAnswers.pdf
PPTX
Final Presentation General Medicine 03-08-2024.pptx
PDF
Anesthesia in Laparoscopic Surgery in India
PPTX
Cell Structure & Organelles in detailed.
PDF
Complications of Minimal Access Surgery at WLH
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PDF
Yogi Goddess Pres Conference Studio Updates
PDF
RMMM.pdf make it easy to upload and study
PPTX
Pharmacology of Heart Failure /Pharmacotherapy of CHF
PDF
Classroom Observation Tools for Teachers
PPTX
Cell Types and Its function , kingdom of life
PPTX
Microbial diseases, their pathogenesis and prophylaxis
PDF
3rd Neelam Sanjeevareddy Memorial Lecture.pdf
PPTX
human mycosis Human fungal infections are called human mycosis..pptx
GENETICS IN BIOLOGY IN SECONDARY LEVEL FORM 3
Weekly quiz Compilation Jan -July 25.pdf
A systematic review of self-coping strategies used by university students to ...
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
01-Introduction-to-Information-Management.pdf
2.FourierTransform-ShortQuestionswithAnswers.pdf
Final Presentation General Medicine 03-08-2024.pptx
Anesthesia in Laparoscopic Surgery in India
Cell Structure & Organelles in detailed.
Complications of Minimal Access Surgery at WLH
Module 4: Burden of Disease Tutorial Slides S2 2025
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
Yogi Goddess Pres Conference Studio Updates
RMMM.pdf make it easy to upload and study
Pharmacology of Heart Failure /Pharmacotherapy of CHF
Classroom Observation Tools for Teachers
Cell Types and Its function , kingdom of life
Microbial diseases, their pathogenesis and prophylaxis
3rd Neelam Sanjeevareddy Memorial Lecture.pdf
human mycosis Human fungal infections are called human mycosis..pptx

2.dynamic

  • 1. Dynamic Support in .NET 4Basharat Hussain
  • 2. List the core areas of C# 4.0Developer should focus on:using the dynamic keyword as a data type that supports runtime lookupusing optional parameters for constructors and methodsexplicitly naming an argument being passing to a methodmaking generic interfaces and delegates covariant/contravariantskipping the passing of optional parameters when making calls to COM objectsomitting the ref keyword when calling a method on a COM objectdynamically importing COM APIs and deploying without Primary InteropAssemblies (PIA)working with the enhanced COM Interop features in C# 4.0using the built-in .NET interfaces like IDynamicMetadataObject in .NET 4.0 – to interact with IronRuby/IronPython
  • 3. Major Theme“ C# 4.0 primarily focus on dynamic programming. "
  • 4. Dynamic DispatchC#4 now supports dynamic late-binding.Helps communicate with systems not based on .NET Platform2 Approaches to communicate Non .NET systems
  • 5. Approach 1 – Using Proxyimport the foreign model directly into .NET as a proxy – like COM InteropCOM Interop - using TLBIMP tool (from C#1)LINQ-to-SQL, contains a tool called SQLMETAL, which imports an existing database into C# proxy classes for use with queries (from C#3)A tool that imports Windows Management Instrumentation (WMI) classes to C#LINQ-to-SQLWCF
  • 6. Approach 2 – use DynamicForget about type safety at compile timeWe already doing things at runtime in C# 3.5 and laterinvokes a method on a JScriptobjectembed a SQL query in your ADO.NET applicationReflection defer binding to run timeInteropin that case is with .NET itself
  • 7. Reflection vs. dynamicReflection object o = GetObject();Type t = o.GetType();objectresult = t.InvokeMember("MyMethod", BindingFlags.InvokeMethod, null, o, newobject[] { });inti = Convert.ToInt32(result);Dynamic dynamic o = GetObject();inti = o.MyMethod();
  • 8. Dynamic KeywordThe dynamic  keyword in C# 4.0Tell compiler – variable type is unknown until runtimedynamic can be thought of as a special version of the type object that is “suspending belief” dynamic is a static type that bypasses static type checkingdynamic d = GetCustomer(); d.FirstName = "foo"; // works as expectedd.Process(); // works as expectedd.MissingMethod(); // No method found!Dynamic declaration meansRuntime sets FirstName propertyRuntime will call Process() methodCompiler is even happy and runtime notice that MissingMethod() is not defined in Customer class Result is exception: RuntimeBinderException 
  • 9. Dynamic UsabilityNeed to cast between decimal and double decimal foo = GetDecimalValue(); foo = foo / 2.5 ; // Code break because 2.5 typed as doublefoo = Math.Sqrt(foo); // Code break because sqrt expects doublestring bar = foo.ToString("c");Dynamic magic in c#4 – No need to castdynamic foo = GetDecimalValue(); // still returns a decimalfoo = foo / 2.5; // The runtime takes care of this for usfoo = Math.Sqrt(foo); // Again, the DLR works its magicstring bar = foo.ToString("c");
  • 10. Static vs. Dynamic SwitchingCustomer c = new Customer(); dynamic d = c; // static to dynamic, easy enoughd.FirstName= "foo"; Customer newCust = d; // Works because d is a CustomerPerson p = d; // works because Customer inherits from PersonSalesRep s = d; // throws RuntimeBinderException exceptionNote: In the example above, no matter how many different ways we reference it, we only have one Customer object (c).
  • 11. RuntimeBinderExceptiontry{dynamic d = "this is a string";d.Foo();}catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException e){Console.WriteLine(e.Message);}Output:'string' does not contain a definition for 'Foo'
  • 12. AssignmentAny object can be implicitly converted to dynamicConversely, there is an “assignment conversion” from dynamic to any other type, provided normal implicit conversion in assignment is allowed – again at runtimedynamic d= GetCustomer(); string first = d.FirstName; // assignmentconversiondynamic id = d.CustomerId; // no conversionobject last = d.LastName; // assignmentconversiondynamic d = 10; //Rule: Dynamic is like object so boxing must happen for value types (explained next slides)
  • 13. The following example throws a RuntimeBinderException because an int is not implicitly convertible to a short:     int i = 7;     dynamic d = i;     short j = d;                // throws RuntimeBinderException
  • 14. Dynamic bindingThe result of any dynamic operation is itself of type dynamicThe process of selecting which operation to apply based on the types of constituent expressions is referred to as binding.Binding OperationsMember access: d.MMethod invocation: d.M(d1,…,dn)Delegate invocaton: d(d1,…,dn)Element access: d[d1,…,dn]Constructor calls: new C(d1,…,dn)Overloaded unary operators: +, -, !, ~, ++, --, true, falseOverloaded binary operators: +, -, *, /, %, &, &&, |, ||, ??, ^, <<, >>, ==,!=, >, <, >=, <=Compound assignment operators: +=, -=, etc.Implicit and explicit conversions
  • 15. PossibilitiesdynamicGetDynamicObject(){returnnewobject();}void Demo(){var d = GetDynamicObject(); // getting as return type d.M(7); // calling methodsd.f = d.P; // getting/settings fields and properties d[“one”] = d[“two”]; // getting/setting through indexersint i = d + 3; // calling operatorsstring s = d(5,7); // invoking as a delegate}
  • 16. Dynamic reusabilityPossible but not recommendedDynamic can reuse a variable for different types of datadynamic foo = 1234567890;System.Console.WriteLine(foo);foo = "John Charles";System.Console.WriteLine(foo);foo = true;System.Console.WriteLine(foo);
  • 17. Dynamic dispatch - by Exampledynamic list = GetDynamicList();dynamicindex1 = GetIndex1();dynamicindex2 = GetIndex2();strings = list[++index1, index2 + 10].Foo();Fivedynamic operations in one line First, there’s the dynamic pre-increment on index1, then the dynamic add with index2. Then a dynamic indexer get is called on list. The product of those operations calls the member Foo. Finally, the total result of the expression is converted to a string and stored in s. That’s five dynamic operations in one line, each dispatched at run time.
  • 18. Dynamic Vs. Object (similarities)Type inference algorithms as described in §7.4 will prefer dynamic over object if both are candidatesThere is an implicit identity conversion between object and dynamicThere is an implicit identity conversion between constructed types that differ only by dynamic versus objectMethod signatures that differ only by dynamic versus object are considered the same and can be overriddenLike with object, there is an implicitconversion from every type (other than pointer types) to dynamic and an explicit conversion from dynamic to every such type.
  • 19. Dynamic vs. Object (similarities)Type dynamic does not have a separate runtime representation from objecttypeof(dynamic) == typeof(object)is trueThis principle extends to constructed types and array typestypeof(List<dynamic>) == typeof(List<object>)typeof(dynamic[]) == typeof(object[])
  • 20. Dynamic vs. object (similarities) This statement is correctList<dynamic> dList = new List<object>();You can override Equals method that take object parameter – with dynamicclass Employee{ public override bool Equals(dynamic obj) { /* ... */ } } Use dynamic as real type argument or, as a return value – even across assembliespublic dynamic GetDynamicThing()
  • 21. Dynamic vs. object (differences) -Boxing Unboxing Object o = 123;             // OK, Implicit cast from Int32 to Object (boxing)Int32 n1 = o;                // Error: No implicit cast from Object to Int32Int32 n2 = (Int32) o;     // OK: Explicit cast from Object to Int32 (unboxing)dynamic d = 123;          // OK: Implicit cast from Int32 to dynamic (boxing)Int32 n3 = d;                //OK: Implicit cast from dynamic to Int32 (unboxing)
  • 22. Dynamic vs. object (differences) - dynamic parameter != object –treat dynamic like actual typesclassMyType{publicvoid Method(int x, int y) { Console.WriteLine("Int function"); }publicvoid Method(string s, string t) { Console.WriteLine("Str function"); }publicvoid Method(object o, object p) { Console.WriteLine(“Obj function"); }}classProgram{staticvoid Main(string[] args) {dynamic d = newMyType();d.Method(10, 20); // Calls the int version.d.Method("abc", "def"); // Calls the string version. d.Method((object)10, (object)20); // Calls the object version.d.Method((object)"abc", (object)"def"); // Calls the object version.// *d.Method((dynamic)10, (dynamic)20); // Calls the int version. (PHANTOM)d.Method((dynamic)"abc", (dynamic)"def"); // Calls the string version.(PHANTOM)// Repeat of the last 4 cases.d.Method(GetInt(), GetInt()); // Calls the object version.d.Method(GetString(), GetString()); // Calls the object version.d.Method(GetDynamicInt(), GetDynamicInt()); // Calls the int version. } staticobjectGetString() {return ("abc"); }staticobjectGetInt() {return (5); }staticdynamicGetDynamicInt() {return (5); }}
  • 23. The result of any dynamic operation is itself of type dynamic, with two exceptions:The type of a dynamic constructor call is the constructed typeThe type of a dynamic implicit or explicit conversion is the target type of the conversion.dynamicis very slow– so use only when necessary otherwise use var.
  • 24. Implicitly Typed Local Variables and ArraysKeyword var - type is inferred by the compiler from the expression on the right side of the initialization statement.Inference type supportBuilt-in typeAnonymous type (will be discussed later)User-defined typeType defined in the .NET Framework class library
  • 25. Var - Usagevarivar = 6 // compiled as an intvarsvar="Mony"; // compiled as a stringvariarr_var=new[] {0,1,2 }; // compiled as int[] - arrayvarsarr_var=new[] {"hello",null,"world" }; // string[]a// query is compiled as IEnumerablevarquery = from c in customerswhere c.Name =="Mony"select c;// anonymous_variable is compiled as an anonymous typevaranonymous_variable =new { Name = “Sami", Job = "Web Developer" };var list =new List();
  • 26. VarRestrictionsIs always local to a method and first time initializationCannot be nullCannot be used as class’s fieldCannot be uses in initialization again with variablevar i = i++;  - compile-time errorMultiple implicitly-typed variables cannot be initialized in the same statement.
  • 27. DLR ArchitectureThe DLR Runs on Top of the CLR
  • 28. DLR ServicesDLR adds three services to the CLR for better supporting dynamic languagesExpression TreesThe same expression trees used in LINQ, now improved to support statements ( language syntaxes and semantics).Call Site CachingFor improved efficiency.Dynamic DispatchDispatches invocations to the appropriate binder.Dynamic Object Interoperability These are essentially a set of interfaces that help creation of dynamic objects.
  • 29. Expression treesThe same expression trees used in LINQ, now improved for DLR to support statements ( language syntaxes and semantics).DLR has extended LINQ expression trees to include control flow, assignment, and other language-modeling nodes
  • 30. Call site cachingA dynamic call site is a place in the code where you perform an operation like a + b or a.b on dynamic objects. DLR Cache usage/ characteristics of dynamic objects a and b. If such operation performed previously, the DLR retrieves all the necessary information from the cache for fast dispatchAlso cache  information about operations on the ‘Dynamic Objects’
  • 31. Dynamic dispatchWikipedia says:“Dynamic dispatch (dynamic binding) is the process of mapping a message to a specific sequence of code (method) at runtime. This is done to support the cases where the appropriate method cannot be determined at compile-time (i.e. statically)”.Binders are used by DLR
  • 32. Dynamic dispatch – underneth bindersUnderneath the DLR there are binders that talk to a variety of different technologies:.NET BinderAllows to talk to .NET objects.JavaScript BinderAllows to talk to JavaScript in SilverLight.IronPython BinderAllows to talk to IronPython.IronRuby BinderAllows to talk to IronRuby.COM BinderAllows to talk to COM.OtherwiseThrow Exception: RuntimeBinderException
  • 33. Dynamic dispatch mechanismRuntime resolution is based on nature of dynamic variableCache Info: Use call site cahe information, if operation on object is previously performedCOM objectsCOM Interopscenarios - Calling through IUnknown and IDispatch interfaces of COMOffice automationDynamic objectsConsuming types written in dynamic languages as IronPython and IronRuby to implement their own dynamic object modelsHTML DOM to allow direct access to the object’s propertiesimplements the interface IDynamicObjectIDynamicMetaObjectProviderPlain objectsUsing reflection against an underlying CLR type
  • 34. Dynamic dispatch - by Exampledynamic d1 = new Foo();dynamic d2 = new Bar();string s;d1.M(s, d2, 3, null);“Perform an instance method call of M with the following arguments:a string a dynamic a literal int 3a literal object null”Resolution Sequence At Runtime: assume that the actual type Foo of d1 is not a COM type And it does not implement IDynamicObjectIDynamicMetaObjectProviderThen proceed following wayUse Reflection and get actual runtime types of the two objects, d1 and d2, >> Foo for d1 and Bar for d2.Method lookup and overload resolution is performed for Foo.M(string,Bar,3,null)If found – inoke itOtherwise throw RuntimeBinderException
  • 35. COM automation interop – dynamicCode in C#3Type myType = Type.GetTypeFromProgID("IMyLib.MyClass"); object obj = Activator.CreateInstance(myType); object[] args = new object[2]; args[0] = "Hello"; args[1] = 3; myType.InvokeMember("MyMethod", BindingFlags.InvokeMethod, null, args);New Code in C#4================Type myType = Type.GetTypeFromProgID("IMyLib.MyClass"); dynamic { object obj = Activator.CreateInstance(myType); obj.MyMethod("Hello", 3); }
  • 36. Limitations of Dynamic LookupExtension methods - not supportedDynamic lookup will not be able to find extension methods. Whether extension methods apply or not depends on the static context of the call.Anonymous functions as parameters - not supportedAnonymous functions (i.e. lambda expressions) cannot appear as arguments to a dynamic method call. The compiler cannot bind (i.e. “understand”) an anonymous function without knowing what type it is converted to
  • 37. Limitation Exampledynamic collection = …;var result = collection.Select(e => e + 5);Select method is an extension method to collection, dynamic lookup will not find it.object collection = context.Students.Select( s=> new { Id = s.Id, Name = s.Name}).ToList();dynamic d = collection;int count = d.Count;Because collection is anonymous type so dynamic cannot understand it.
  • 38. The Visitor Pattern and dynamic in C# 4http://code.logos.com/blog/2010/03/the_visitor_pattern_and_dynamic_in_c_4.htmlDynamic can even avoid Visitor Pattern in some casespublicclassMySpecialFunctions{ publicvoid Execute(int x) {...} publicvoid Execute(string x) {...} publicvoid Execute(long x) {...} }With Multi-dispatch casedynamic x = getx(); varmyFunc = newMySpecialFunctions(); myFunc.Execute(x);
  • 40. IDynamicMetaObjectProviderTells the DLR, "I know how to dispatch operations on myself.“This interface contains single method:DynamicMetaObjectGetMetaObject (Expression parameter)Blog Examplehttp://blogs.msdn.com/b/cburrows/archive/2008/10/28/c-dynamic-part-ii.aspx
  • 41. Framework implementationsThe .NET Framework already provides two implementations of IDynamicMetaObjectProvider:ExpandoObject: IDynamicMetaObjectProviderDynamicObject: IDynamicMetaObjectProvider
  • 42. ExpandoObject Expandosare expandable objects which means you can add properties, methods and even events at runtime. You can also set and get the values of such members.Can also pass Expando objects as parameters to other methodsLimitation: Will not get intellisense on the dynamic object because they are resolved at runtimeMSDN Example: http://msdn.microsoft.com/library/system.dynamic.expandoobject.aspx
  • 43. Example – Expando Objectusing System;usingSystem.Dynamic;namespaceDLRExample{classProgram {staticvoid Main(string[] args) {dynamic Vehicle = newExpandoObject();Vehicle.Make = "Cultus";Vehicle.Model = "2008";Vehicle.Engine = "4 cylinder";Vehicle.Color = "Silver";WriteVehicleDetails(Vehicle);Console.ReadLine(); }staticvoidWriteVehicleDetails(dynamicvehicleobject) {Console.WriteLine("The make of the vehicle is {0}", vehicleobject.Make);Console.WriteLine("The color of the vehicle is {0}", vehicleobject.Color); } }}
  • 44. ExpandoObject – CONT…Can add methods at runtime - using lambda expressions. Example: add method ChangeVehicleColor() to ExpandoObject - that changes color of the vehicle to whitedynamic Vehicle = newExpandoObject();Vehicle.Make = "Ford";Vehicle.Model = "Endeavour";Vehicle.Engine = "4 cylinder";Vehicle.Color = "Black";Vehicle.ChangeVehicleColor = (Action)(() => {Vehicle.Color="White";});WriteVehicleDetails(Vehicle);Vehicle.ChangeVehicleColor();WriteVehicleDetails(Vehicle);
  • 45. ExpandoObject – CONT…expando object also implements the generic IDictionaryinterfaceSo you can enumerate the members of the object, if need.dynamic vehicle = newExpandoObject();vehicle.Make = "Cultus";vehicle.Model = "2008";vehicle.Engine = "4 cylinder";vehicle.Color = "Silver";EnumerateMembers(vehicle);=============================staticvoidEnumerateMembers(dynamicvehicleObject){foreach (var property in (IDictionary<String, Object>)vehicleObject) {Console.WriteLine(property.Key + ": " + property.Value); }}
  • 46. DynamicObjectProvides a base class for specifying dynamic behavior at run time. This class must be inherited from; User cannot instantiate DynamicObjectdirectly while ExpandoObject can.The DynamicObject class - define which operations can be performed on dynamic objects and howto perform those operationsMSDN Example: http://msdn.microsoft.com/library/system.dynamic.dynamicobject.aspxInterstingOppertunity: Receiver Object have an opportunity to inject it self into binding at runtimeSo Object can determine the semantics of any dynamic operation (like dynamic method call) –TryInvokeMemberknows how to handle it?
  • 47. My Dynamic Object ImplementationCaller Codedynamic d = newMyDynamicObject(); d.Bar("Baz", 3, d);So the call to Bar Compiler don’t know anything at compile timeRun time, the object itself is asked what to do with this call to Bar. That’s what TryInvokeMember knows how to handle.Definition of My Dynamic classclassMyDynamicObject : DynamicObject{publicoverrideboolTryInvokeMember(InvokeMemberBinder binder, object[] args, outobject result) {Console.WriteLine("Method: {0}", binder.Name);foreach (var arg in args) {Console.WriteLine("Argument: {0}", arg); }result = args[0];returntrue; }}Output of this code is:Method: Bar Argument: BazArgument: 3 Argument: MyDynamicObject
  • 48. UsageThe Expando object is interoperable between different framework languages. So it is an obvious choice in situations where you have to pass objects between different framework languages that support the DLR interoperability model (IronPython, IronRuby).The Dynamic object is a good choice for interacting with COM interops. Useful to also be used with scripting objects (HTML DOM from Sliverlight).If these two objects don’t do the trick for you, remember you can always create your own dynamic objects by implementing the IDynamicMetaObjectProviderinterface.
  • 50. The Phantom MethodRule of thumb:Everything is convertible to dynamic – Implicit ConversionDynamic is not convertible to anything – Explicit Conversion or Assignment Conversion
  • 51. phantom methodpublicclassC{publicvoid Foo(int x) { }staticvoid Main() {dynamic d = 10;Cc = newC();c.Foo(d); }}c.Foo(d) call contain dynamic, where assignment conversion is needed. Foo(int) is not suffucent. Foo(dynamic) overload is needed
  • 52. phantom methodIn each of these special situations compiler generates all the surrounding DLR code that prompts a runtime conversion.The special situations in question are the following:Overload resolution - c.Foo(d)Assignment conversion - C c = dConditionals - if (d)Using clauses - using (dynamic d = ...)Foreach - foreach (var c in d)Where c is static while d dynamic variable
  • 53. Overload resolution – phantom methodSince dynamic (d) is not convertible to anything (int), however, since we've got a dynamically typed argument, we really want the overload resolution for this call to be bound dynamically. Enter the phantom method.The phantom method is a (overload) method which is introduced into the candidate set that has the same number of parameters as the number of arguments given, and each of those parameters is typed dynamic.C.Foo(d) will bind to this Phantommethod Foo(dynamic), not Foo(int).
  • 54. phantom methodIf compiler detects C.Foo(d) taking dynamic as parameterIt genertaes two overloads: Foo(int) and Foo(dynamic). The first overload fails because dynamic is not convertible to int. The second, the phantom, succeeds and so we bind to it.Once a call is bound to the phantom overload, the compiler knows to generate the correct DLR magic to signal dispatching the call at runtime.Question remains: when does the phantom overload not generated?
  • 55. phantom methodThe phantom will be introduced if:All of the non-dynamic arguments are convertible to their respective parameters.At least one of the dynamic arguments is not convertible to its respective parameter. It would be possible for a call containing a dynamic argument to be dispatched statically instead of dynamically
  • 56. phantom methodpublicclassC{publicvoid Foo(int x, dynamic y) { ... }staticvoid Main() {Cc = newC();dynamic d = 10;c.Foo(10, d); }}No phantom overload created in candidate setinitial binding pass and overload resolution behave like normal - despite the occurrence of a dynamic parameter
  • 58. Mutating values Types using dynamicdynamicd = 10;d++;Console.WriteLine(d); //d=11If right side is value type then dynamic behave like and object and boxing takes place.Variable d contains boxed copy of integer valueAt runtime, ++ operator on d means unbox first into integer, then increment unboxed value, but value is not copied back inside box. Problem … because .Net/CLR have no ability on ref returns Solution: There is an expression tree that performs an unbox and modifies the boxed value, and puts that value back into the box, allowing you to mutate the boxed values of these things.
  • 59. Nested structmutationExtending last issue on value type, if any of the dotted expressions were to bind to a value type, that value will be boxed (and hence a copy would be made), and further dots into it would be made on the copy of the value, and not the initial value as would be expected. Introduced bug in following example
  • 60. Nested structmutation - ExamplepublicstructS{publicint i;} publicclassD{publicSs;publicvoid Execute() {dynamic d = newD();d.s = default(S);d.s.i = 10;Console.WriteLine(d.s.i); }}d.s.i will print 0 ???
  • 61. Base callsThere is a restriction in the CLR that prevents the compiler from generating non-virtual calls on virtual methods. This means that there is no way to call a base overload dynamically. This means that one cannot call a base call with any dynamically typed arguments, as it will trigger a dynamic binding.
  • 62. Explicitly implemented interface methods not supportedInterfaces are really compile time constructs, and have no runtime representation, explicitly implemented interface members get lost.interfaceIFoo{void M();}classC : IFoo{voidIFoo.M() { }}C.M() is never callable from dynamic.
  • 63. No phantom for privateThe down side of this scenario is that you could make a call with a static receiver to a private method that you know you can access from your context, but because a dynamic argument is given, the runtime binder will prevent you from calling the method.publicclassC{privatevoid M(int x) { }staticvoid Main() {dynamic d = 10;Cc = newC();c.M(d); }}Complier will succeed because c.M() is accessiblein Main. Since argument is dynamic, call is resolved at runtime, Runtime binder have public only policy, so it will not generate Phantom overload with signature M(dynamic). So overload resolution will not bind to the method
  • 65. Static or dynamic?publicclassC{staticvoid Main() {Cc = newC();dynamic d = 10;c.Foo(d, 10); // (1) Static Operationd.Foo(10, 10); // (2) Dynamic Operation }publicvoid Foo<T, S>(T x, S y) { }}The first call is a statically known receiver with a dynamically typed argument. The second is a dynamically typed receiver with a statically known argument.
  • 66. Compiler ignores type inference of parameter type (and constraints)Compiler assumes it is convertible at compile time, so skipping type inference may result unexpected resultspublicclassC{staticvoid Main() {Cc = newC();dynamic d = 10;c.Foo(10, d); }publicvoid Foo<T>(T t, int x) where T : class { }}Compiler currently allow this call to compile successfully and fail at runtime!Bug in Type Inference algorithm
  • 67. A complex scenariopublicinterfaceIAnimal { }publicinterfaceIWatcher<in T> { } //Contravariant in TpublicclassWatcher<T> : IWatcher<T> { }publicclassC{staticvoid Main(string[] args) {Cc = newC();IWatcher<Giraffe> a = newWatcher<Giraffe>();IWatcher<Monkey> b = newWatcher<Monkey>();dynamic d1 = 10;dynamic d2 = newWatcher<Mammal>();IWatcher<dynamic> d3 = newWatcher<dynamic>();c.Bar(a, b, d1); // (1)c.Bar(a, b, d2); // (2)c.Bar(a, b, d3); // (3) }publicvoid Bar<T>(IWatcher<T> w1, IWatcher<T> w3, IWatcher<T> w2) where T : IAnimal { }}publicclassMammal : IAnimal { }publicclassGiraffe : Mammal { }publicclassMonkey : Mammal { }
  • 68. Analysis of ExampleIn the first call, this is all fine and good - runtime type inference would also fail on the call. Even 10 is not Ianimal – but belief is suspended for dynamic.However, the second call will succeed at runtime! Because the runtime type of d2 is Watcher<Mammal>, Mammal is added to the candidate set. And because IWatcher is covariant on T, choosing T to be Mammal satisfies argument convertibility for each of the three argumentsThe third call will fail at compile time, because the candidate set for T is {Giraffe, Monkey, dynamic}, and T is not marked inconclusive. Type inference will infer T to be dynamic, since it is the common base class and IWatcher is covariant. However, constraint checking will fail, since dynamic is not an IAnimal.
  • 69. Language InteroperabilityCalling from/to .NET the dynamic objects written in IronPythonIronRuby
  • 70. IronPython Installationhttp://ironpython.net/http://ironpython.codeplex.com/releases/view/54498Iron Python V2.7 - download and install Open-source implementation of the Python programming language which is tightly integrated with the .NET Framework.DLLs path is C:\Program Files\IronPython 2.7IronPython.dllIronPython.Modules.dllMicrosoft.Scripting.dllMicrosoft.Scripting.Core.dll
  • 71. Invoke IronPython from C#Instantiating the IronPython object from C#4 - using dynamicSteps:Ensure IronPython installedCreate simple console applicationReference DLLs from installed directoryWrite hello.py scriptUse dynamic to create and call IronPython methodHello.pyclass Hello:def __init__(self): passdef add(self, x, y): return (x+y)
  • 72. Invoke IronPythonfrom C#var runtime = Python.CreateRuntime();var scope = runtime.ExecuteFile(@"..\..\scripts\hello.py");var ops = runtime.Operations;varpythonType = scope.GetVariable("Hello");dynamic instance = ops.CreateInstance(pythonType);var value = instance.add(10, 20); //Result = 30Console.WriteLine(value);
  • 73. Invoke C# “Dynamic Object” from C#/IronPythonpublicclassMyDynamicObject : DynamicObject {publicvoid Foo() {Console.WriteLine("Foo() Called"); }publicoverrideDynamicMetaObjectGetMetaObject(System.Linq.Expressions.Expression parameter) {Console.WriteLine("GetMetaObject() Called");returnbase.GetMetaObject(parameter); }publicoverrideboolTryInvokeMember(InvokeMemberBinder binder, object[] args, outobject result) {Console.WriteLine("TryInvokeMember() Called");returnbase.TryInvokeMember(binder, args, out result); }publicoverrideboolTryGetMember(GetMemberBinder binder, outobject result) {Console.WriteLine("TryGetMember() Called");returnbase.TryGetMember(binder, out result); }}(Cont.….)
  • 74. Invoke C# “Dynamic Object” from C#/IronPythonpublicstaticvoid Execute(){ dynamic myDynamicObject = newMyDynamicObject();//first tey calling this object from C#, it should call Foo() and they try to call MissingMethod();Console.WriteLine("C# Test...");try {myDynamicObject.Foo();myDynamicObject.MissingMethod(); }catch (Exception ex) {Console.WriteLine("Got C# exception: " + ex.Message); }ScriptEnginepythonEngine = Python.CreateEngine();ScriptScopescriptScope = pythonEngine.CreateScope();stringpythonScript = SetPythonScript();ScriptSource script = pythonEngine.CreateScriptSourceFromString(pythonScript, SourceCodeKind.Statements);scriptScope.SetVariable("myDynamicObject", myDynamicObject);//Now do the same thing from python, I expect to get the same behaviour as from C# Console.WriteLine("\r\nScript Test...");try {script.Execute(scriptScope); }catch (Exception ex) {Console.WriteLine("Got script exception: " + ex.Message); }}staticstringSetPythonScript(){string s = ""; s += "import clr" + "\r\n"; s += "clr.AddReference('mscorlib')" + "\r\n"; s += "myDynamicObject.Foo();" + "\r\n"; s += "myDynamicObject.MissingMethod();" + "\r\n";return s;}
  • 75. IronRuby Installationhttp://www.ironruby.net/http://ironruby.codeplex.com/releases/view/25901Iron Ruby V1.0 - download and install Open-source implementation of the Ruby programming language which is tightly integrated with the .NET Framework.DLLs path is C:\Program Files (x86)\IronRuby 1.0v4\binIronRuby.dllIronRuby.Libraries.dllIronRuby.Libraries.Yaml.dllMicrosoft.Dynamic.dllMicrosoft.Scripting.Debugging.dllMicrosoft.Scripting.dllMicrosoft.Scripting.Silverlight.dllSystem.Numerics.dll
  • 76. Problem with Framework DesignersDynamic Lacks documentationLack compile-time type checkingLack PerformanceLosing IntelliSense
  • 77. Lacks documentationSevere lack of documentation. The entire application's architecture exists in the mind of the person (or persons) who wrote it. At least with strong-typing, you can go see what the object does via its class definition. With dynamic-typing, you must infer the meaning from it's use, at best. At worst, you have NO IDEA what the object is. It's like programming everything in JavaScript
  • 78. Lack compile-time type checking>>Dynamic Versionpublicdynamic Foo(dynamic other){dynamic clone = other.Clone();clone.AssignData(this.Data);return clone;}>>Typed Versionpublic T Foo<T>(T other) where T : ICloneable, IAssignData{ T clone = (T)other.Clone();clone.AssignData(this.Data);return clone;} Critic: First one has no static type info, no compile time checking, it's not self documenting, no type inference so people will be forced to use a dynamic reference at the call site to store the result, leading to more type loss
  • 79. Don’t Use BlindlyAnswer: Use dynamic-only-when-necessary and var-at-all-other-timesPurpose of dynamic includeinteroperability with dynamic languages and platforms such as COM/C++ and DLR/IronPython/IronRubyturning C# itself implementing IDynamicObject
  • 80. Very Bad PerformanceIf dynamicusage can be avoided, it should be avoided.Statistical performance studydynamic c = 10; int b = c * c; Above code is nice and very easy to read but very slow.Comparisons:Using regular reflection, you can't use defined operators. About 10,000 times slower than a regular multiplication About 100 times slower than an ICalculatorinterface with a Multiply methodUseful Link: http://blogs.msdn.com/b/lucabol/archive/2009/02/05/simulating-inumeric-with-dynamic-in-c-4-0.aspx
  • 81. Generated Code – for interested onesdynamic c = 10; int b = c * c; 
  • 82. HTML DOMIf you write Silverlight applications, you might have the need today or in the future to access the HTML DOM containing your Silverlight control. C# dynamic programming makes this task easier.
  • 83. HTML DOMExpects Dynamic Dispatch from JScriptJScript:var loc = new VELatLong(latitude, longitude);var pin = map.AddPushpin(loc);pin.SetTitle(title);pin.SetDescription(description);map.SetCenterAndZoom(loc, 7);C# 3.0 (Silverlight):ScriptObject loc = win.CreateInstance( "VELatLong", lat, long)ScriptObject pin = (ScriptObject)map.Invoke("AddPushpin", loc);pin.Invoke("SetTitle", title);pin.Invoke("SetDescription", description);map.Invoke("SetCenterAndZoom", loc, 7);dynamic loc = win.New.VELatLong(latitude, longitude)var pin = map.AddPushpin(loc);pin.SetTitle(title);pin.SetDescription(description);map.SetCenterAndZoom(loc, 7);C# 4.0 (Silverlight):
  • 84. Runtime semantics/sequence of dynamic bindingIf the receiver is a dynamic object – i.e., implements IDynamicMetaObjectProvider– the object itself programmatically defines the resolution of the operations performed on it.
  • 85. Otherwise the operation gets resolved at runtime in the same way as it would have at compile time, using the runtime type of any constituent value statically typed as dynamic and the compile time type of any other constituent value.
  • 86. If a constituent value derives from a literal, the dynamic binding is able to take that into account. For instance, some conversions are available only on literals.
  • 87. If a constituent value of static type dynamic has the runtime value null, it will be treated as if the literal null was used.
  • 88. Extension method invocations will not be considered – the set of available extension methods at the site of the call is not preserved for the runtime binding to use.
  • 89. If the runtime binding of the operation succeeds, the operation is immediately performed,otherwise a runtime error occurCOM Interfaces - rewrittenIntrop assemblies are rewritten to support named parameter and dynamic
  • 90. Online ResourcesC# Future Download Page:http://code.msdn.microsoft.com/csharpfutureSilverlightStarter project available in the CSharpDynamicSamplesdownloadVB Future Download Page:http://code.msdn.microsoft.com/vbfutureIronPython CTP Release:http://go.microsoft.com/fwlink/?LinkId=129196And to all sources on Blogs, Forums and pages – don’t track usually
  • 91. About MeBasharat HussainSolution ArchitectTEO (Pvt.) Ltd. 3rd Floor, Hassan Arcade, F-11 Markaz, Islamabad, PakistanMail: basharat@live.comBlog: http://basharatspace.blogspot.com/
  • 92. Q&A