• Save
2.dynamic
Upcoming SlideShare
Loading in...5
×
 

2.dynamic

on

  • 2,074 views

C# 4.0 is now dynamic language. DLR feature is remarkable. See how you can get benefit from dynamicity.

C# 4.0 is now dynamic language. DLR feature is remarkable. See how you can get benefit from dynamicity.

Statistics

Views

Total Views
2,074
Views on SlideShare
1,663
Embed Views
411

Actions

Likes
1
Downloads
0
Comments
0

30 Embeds 411

http://basharatspace.blogspot.com 283
http://basharatspace.blogspot.in 51
http://basharatspace.blogspot.de 15
http://basharatspace.blogspot.co.uk 10
http://basharatspace.blogspot.hu 6
http://basharatspace.blogspot.ca 4
http://basharatspace.blogspot.fr 4
http://basharatspace.blogspot.sg 4
http://basharatspace.blogspot.se 3
http://basharatspace.blogspot.pt 3
http://basharatspace.blogspot.nl 3
http://basharatspace.blogspot.co.at 2
http://basharatspace.blogspot.ie 2
http://basharatspace.blogspot.dk 2
http://basharatspace.blogspot.com.ar 2
http://basharatspace.blogspot.co.il 2
http://basharatspace.blogspot.com.au 2
http://basharatspace.blogspot.co.nz 1
http://basharatspace.blogspot.ru 1
http://basharatspace.blogspot.com.es 1
http://basharatspace.blogspot.no 1
http://www.slideshare.net 1
http://basharatspace.blogspot.kr 1
http://basharatspace.blogspot.hk 1
http://basharatspace.blogspot.mx 1
http://basharatspace.blogspot.ch 1
http://basharatspace.blogspot.be 1
http://basharatspace.blogspot.cz 1
http://basharatspace.blogspot.jp 1
http://basharatspace.blogspot.tw 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

2.dynamic 2.dynamic Presentation Transcript

  • Dynamic Support in .NET 4
    Basharat Hussain
  • List the core areas of C# 4.0
    Developer should focus on:
    using the dynamic keyword as a data type that supports runtime lookup
    using optional parameters for constructors and methods
    explicitly naming an argument being passing to a method
    making generic interfaces and delegates covariant/contravariant
    skipping the passing of optional parameters when making calls to COM objects
    omitting the ref keyword when calling a method on a COM object
    dynamically importing COM APIs and deploying without Primary InteropAssemblies (PIA)
    working with the enhanced COM Interop features in C# 4.0
    using 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 Dispatch
    C#4 now supports dynamic late-binding.
    Helps communicate with systems not based on .NET Platform
    2 Approaches to communicate Non .NET systems
  • Approach 1 – Using Proxy
    import the foreign model directly into .NET as a proxy – like COM Interop
    COM 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-SQL
    WCF
  • Approach 2 – use Dynamic
    Forget about type safety at compile time
    We already doing things at runtime in C# 3.5 and later
    invokes a method on a JScriptobject
    embed a SQL query in your ADO.NET application
    Reflection
    defer binding to run time
    Interopin that case is with .NET itself
  • Reflection vs. dynamic
    Reflection
    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 Keyword
    The dynamic  keyword in C# 4.0
    Tell compiler – variable type is unknown until runtime
    dynamic 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 checking
    dynamic d = GetCustomer();
    d.FirstName = "foo"; // works as expected
    d.Process(); // works as expected
    d.MissingMethod(); // No method found!
    Dynamic declaration means
    Runtime sets FirstName property
    Runtime will call Process() method
    Compiler is even happy and runtime notice that MissingMethod() is not defined in Customer class
    Result is exception: RuntimeBinderException 
  • Dynamic Usability
    Need to cast between decimal and double
    decimal foo = GetDecimalValue();
    foo = foo / 2.5 ; // Code break because 2.5 typed as double
    foo = Math.Sqrt(foo); // Code break because sqrt expects double
    string bar = foo.ToString("c");
    Dynamic magic in c#4 – No need to cast
    dynamic foo = GetDecimalValue(); // still returns a decimal
    foo = foo / 2.5; // The runtime takes care of this for us
    foo = Math.Sqrt(foo); // Again, the DLR works its magic
    string bar = foo.ToString("c");
  • Static vs. Dynamic Switching
    Customer c = new Customer();
    dynamic d = c; // static to dynamic, easy enough
    d.FirstName= "foo";
    Customer newCust = d; // Works because d is a Customer
    Person p = d; // works because Customer inherits from Person
    SalesRep s = d; // throws RuntimeBinderException exception
    Note: In the example above, no matter how many different ways we reference it, we only have one Customer object (c).
  • RuntimeBinderException
    try
    {
    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'
  • Assignment
    Any object can be implicitly converted to dynamic
    Conversely, there is an “assignment conversion” from dynamic to any other type, provided normal implicit conversion in assignment is allowed – again at runtime
    dynamic d= GetCustomer();
    string first = d.FirstName; // assignmentconversion
    dynamic id = d.CustomerId; // no conversion
    object last = d.LastName; // assignmentconversion
    dynamic 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 binding
    The result of any dynamic operation is itself of type dynamic
    The process of selecting which operation to apply based on the types of constituent expressions is referred to as binding.
    Binding Operations
    Member access: d.M
    Method 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, false
    Overloaded binary operators: +, -, *, /, %, &, &&, |, ||, ??, ^, <<, >>, ==,!=, >, <, >=, <=
    Compound assignment operators: +=, -=, etc.
    Implicit and explicit conversions
  • Possibilities
    dynamicGetDynamicObject()
    {
    returnnewobject();
    }
    void Demo()
    {
    var d = GetDynamicObject(); // getting as return type
    d.M(7); // calling methods
    d.f = d.P; // getting/settings fields and properties
    d[“one”] = d[“two”]; // getting/setting through indexers
    int i = d + 3; // calling operators
    string s = d(5,7); // invoking as a delegate
    }
  • Dynamic reusability
    Possible but not recommended
    Dynamic can reuse a variable for different types of data
    dynamic foo = 1234567890;
    System.Console.WriteLine(foo);
    foo = "John Charles";
    System.Console.WriteLine(foo);
    foo = true;
    System.Console.WriteLine(foo);
  • Dynamic dispatch - by Example
    dynamic 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 candidates
    There is an implicit identity conversion between object and dynamic
    There is an implicit identity conversion between constructed types that differ only by dynamic versus object
    Method signatures that differ only by dynamic versus object are considered the same and can be overridden
    Like 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 object
    typeof(dynamic) == typeof(object)is true
    This principle extends to constructed types and array types
    typeof(List<dynamic>) == typeof(List<object>)
    typeof(dynamic[]) == typeof(object[])
  • Dynamic vs. object (similarities)
    This statement is correct
    List<dynamic> dList = new List<object>();
    You can override Equals method that take object parameter – with dynamic
    class Employee
    {
    public override bool Equals(dynamic obj) { /* ... */ }
    }
     Use dynamic as real type argument or, as a return value – even across assemblies
    public 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 Int32
    Int32 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 types
    classMyType
    {
    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 type
    The 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 Arrays
    Keyword var - type is inferred by the compiler from the expression on the right side of the initialization statement.
    Inference type support
    Built-in type
    Anonymous type (will be discussed later)
    User-defined type
    Type defined in the .NET Framework class library
  • Var - Usage
    varivar = 6 // compiled as an int
    varsvar="Mony"; // compiled as a string
    variarr_var=new[] {0,1,2 }; // compiled as int[] - array
    varsarr_var=new[] {"hello",null,"world" }; // string[]a
    // query is compiled as IEnumerable
    varquery = from c in customerswhere c.Name =="Mony"select c;
    // anonymous_variable is compiled as an anonymous type
    varanonymous_variable =new { Name = “Sami", Job = "Web Developer" };
    var list =new List();
  • VarRestrictions
    Is always local to a method and first time initialization
    Cannot be null
    Cannot be used as class’s field
    Cannot be uses in initialization again with variable
    var i = i++;  - compile-time error
    Multiple implicitly-typed variables cannot be initialized in the same statement.
  • DLR Architecture
    The DLR Runs on Top of the CLR
  • DLR Services
    DLR adds three services to the CLR for better supporting dynamic languages
    Expression Trees
    The same expression trees used in LINQ, now improved to support statements ( language syntaxes and semantics).
    Call Site Caching
    For improved efficiency.
    Dynamic Dispatch
    Dispatches invocations to the appropriate binder.
    Dynamic Object Interoperability
    These are essentially a set of interfaces that help creation of dynamic objects.
  • Expression trees
    • The 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 caching
    A 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 dispatch
    Also cache  information about operations on the ‘Dynamic Objects’
  • Dynamic dispatch
    Wikipedia 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 binders
    Underneath the DLR there are binders that talk to a variety of different technologies:
    .NET Binder
    Allows to talk to .NET objects.
    JavaScript Binder
    Allows to talk to JavaScript in SilverLight.
    IronPython Binder
    Allows to talk to IronPython.
    IronRuby Binder
    Allows to talk to IronRuby.
    COM Binder
    Allows to talk to COM.
    Otherwise
    Throw Exception: RuntimeBinderException
  • Dynamic dispatch mechanism
    Runtime resolution is based on nature of dynamic variable
    Cache Info:
    Use call site cahe information, if operation on object is previously performed
    COM objects
    COM Interopscenarios - Calling through IUnknown and IDispatch interfaces of COM
    Office automation
    Dynamic objects
    Consuming types written in dynamic languages as IronPython and IronRuby to implement their own dynamic object models
    HTML DOM to allow direct access to the object’s properties
    implements the interface IDynamicObjectIDynamicMetaObjectProvider
    Plain objects
    Using reflection against an underlying CLR type
  • Dynamic dispatch - by Example
    dynamic 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 3
    a 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 IDynamicObjectIDynamicMetaObjectProvider
    Then proceed following way
    Use 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 it
    Otherwise throw RuntimeBinderException
  • COM automation interop – dynamic
    Code in C#3
    Type 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 Lookup
    Extension methods - not supported
    Dynamic 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 supported
    Anonymous 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 Example
    dynamic 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# 4
    http://code.logos.com/blog/2010/03/the_visitor_pattern_and_dynamic_in_c_4.html
    Dynamic can even avoid Visitor Pattern in some cases
    publicclassMySpecialFunctions
    {
    publicvoid Execute(int x) {...}
    publicvoid Execute(string x) {...}
    publicvoid Execute(long x) {...}
    }
    With Multi-dispatch case
    dynamic x = getx();
    varmyFunc = newMySpecialFunctions();
    myFunc.Execute(x);
  • IDynamicMetaObjectProvider
  • IDynamicMetaObjectProvider
    Tells the DLR, "I know how to dispatch operations on myself.“
    This interface contains single method:
    DynamicMetaObjectGetMetaObject (Expression parameter)
    Blog Example
    http://blogs.msdn.com/b/cburrows/archive/2008/10/28/c-dynamic-part-ii.aspx
  • Framework implementations
    The .NET Framework already provides two implementations of IDynamicMetaObjectProvider:
    ExpandoObject: IDynamicMetaObjectProvider
    DynamicObject: 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 methods
    Limitation: Will not get intellisense on the dynamic object because they are resolved at runtime
    MSDN Example: http://msdn.microsoft.com/library/system.dynamic.expandoobject.aspx
  • Example – Expando Object
    using 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 white
    dynamic 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 IDictionaryinterface
    So 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);
    }
    }
  • DynamicObject
    Provides 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 operations
    MSDN Example: http://msdn.microsoft.com/library/system.dynamic.dynamicobject.aspx
    InterstingOppertunity: Receiver Object have an opportunity to inject it self into binding at runtime
    So Object can determine the semantics of any dynamic operation (like dynamic method call) –TryInvokeMemberknows how to handle it?
  • My Dynamic Object Implementation
    Caller Code
    dynamic d = newMyDynamicObject();
    d.Bar("Baz", 3, d);
    So the call to Bar
    Compiler don’t know anything at compile time
    Run 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 class
    classMyDynamicObject : 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: Baz
    Argument: 3
    Argument: MyDynamicObject
  • Usage
    The 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 Method
    Rule of thumb:
    Everything is convertible to dynamic – Implicit Conversion
    Dynamic is not convertible to anything – Explicit Conversion or Assignment Conversion
  • phantom method
    publicclassC
    {
    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 method
    In 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 = d
    Conditionals - if (d)
    Using clauses - using (dynamic d = ...)
    Foreach - foreach (var c in d)
    Where c is static while d dynamic variable
  • Overload resolution – phantom method
    Since 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 method
    If compiler detects C.Foo(d) taking dynamic as parameter
    It 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 method
    The 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 method
    publicclassC
    {
    publicvoid Foo(int x, dynamic y) { ... }
    staticvoid Main()
    {
    Cc = newC();
    dynamic d = 10;
    c.Foo(10, d);
    }
    }
    No phantom overload created in candidate set
    initial binding pass and overload resolution behave like normal - despite the occurrence of a dynamic parameter
  • Advanced Dynamic Limitations
  • Mutating values Types using dynamic
    dynamicd = 10;
    d++;
    Console.WriteLine(d); //d=11
    If right side is value type then dynamic behave like and object and boxing takes place.
    Variable d contains boxed copy of integer value
    At 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 structmutation
    Extending 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 - Example
    publicstructS
    {
    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 calls
    There 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 supported
    Interfaces 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 private
    The 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 Operation
    d.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 results
    publicclassC
    {
    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 scenario
    publicinterfaceIAnimal { }
    publicinterfaceIWatcher<in T> { } //Contravariant in T
    publicclassWatcher<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 Example
    In 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 arguments
    The 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 Interoperability
    Calling from/to .NET the dynamic objects written in
    IronPython
    IronRuby
  • IronPython Installation
    http://ironpython.net/
    http://ironpython.codeplex.com/releases/view/54498
    Iron 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 FilesIronPython 2.7
    IronPython.dll
    IronPython.Modules.dll
    Microsoft.Scripting.dll
    Microsoft.Scripting.Core.dll
  • Invoke IronPython from C#
    Instantiating the IronPython object from C#4 - using dynamic
    Steps:
    Ensure IronPython installed
    Create simple console application
    Reference DLLs from installed directory
    Write hello.py script
    Use dynamic to create and call IronPython method
    Hello.py
    class Hello:
    def __init__(self):
    pass
    def add(self, x, y):
    return (x+y)
  • Invoke IronPythonfrom C#
    var runtime = Python.CreateRuntime();
    var scope = runtime.ExecuteFile(@"....scriptshello.py");
    var ops = runtime.Operations;
    varpythonType = scope.GetVariable("Hello");
    dynamic instance = ops.CreateInstance(pythonType);
    var value = instance.add(10, 20); //Result = 30
    Console.WriteLine(value);
  • Invoke C# “Dynamic Object” from C#/IronPython
    publicclassMyDynamicObject : 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#/IronPython
    publicstaticvoid 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("rnScript Test...");
    try
    {
    script.Execute(scriptScope);
    }
    catch (Exception ex)
    {
    Console.WriteLine("Got script exception: " + ex.Message);
    }
    }
    staticstringSetPythonScript()
    {
    string s = "";
    s += "import clr" + "rn";
    s += "clr.AddReference('mscorlib')" + "rn";
    s += "myDynamicObject.Foo();" + "rn";
    s += "myDynamicObject.MissingMethod();" + "rn";
    return s;
    }
  • IronRuby Installation
    http://www.ironruby.net/
    http://ironruby.codeplex.com/releases/view/25901
    Iron 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.0v4bin
    IronRuby.dll
    IronRuby.Libraries.dll
    IronRuby.Libraries.Yaml.dll
    Microsoft.Dynamic.dll
    Microsoft.Scripting.Debugging.dll
    Microsoft.Scripting.dll
    Microsoft.Scripting.Silverlight.dll
    System.Numerics.dll
  • Problem with Framework Designers
    Dynamic
    Lacks documentation
    Lack compile-time type checking
    Lack Performance
    Losing IntelliSense
  • Lacks documentation
    Severe 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 Version
    publicdynamic Foo(dynamic other)
    {
    dynamic clone = other.Clone();
    clone.AssignData(this.Data);
    return clone;
    }
    >>Typed Version
    public 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 Blindly
    Answer:
    Use dynamic-only-when-necessary and var-at-all-other-times
    Purpose of dynamic include
    interoperability with dynamic languages and platforms such as COM/C++ and DLR/IronPython/IronRuby
    turning C# itself implementing IDynamicObject
  • Very Bad Performance
    If dynamicusage can be avoided, it should be avoided.
    Statistical performance study
    dynamic 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 method
    Useful Link: http://blogs.msdn.com/b/lucabol/archive/2009/02/05/simulating-inumeric-with-dynamic-in-c-4-0.aspx
  • Generated Code – for interested ones
    dynamic c = 10; int b = c * c; 
  • HTML DOM
    If 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 JScript
    JScript:
    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 binding
    • If 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.
    • If the runtime binding of the operation succeeds, the operation is immediately performed,otherwise a runtime error occur
  • COM Interfaces - rewritten
    Introp assemblies are rewritten to support named parameter and dynamic
  • Online Resources
    C# Future Download Page:
    http://code.msdn.microsoft.com/csharpfuture
    SilverlightStarter project available in the CSharpDynamicSamplesdownload
    VB Future Download Page:
    http://code.msdn.microsoft.com/vbfuture
    IronPython CTP Release:
    http://go.microsoft.com/fwlink/?LinkId=129196
    And to all sources on Blogs, Forums and pages – don’t track usually
  • About Me
    Basharat Hussain
    Solution Architect
    TEO (Pvt.) Ltd. 3rd Floor, Hassan Arcade, F-11 Markaz, Islamabad, Pakistan
    Mail: basharat@live.com
    Blog: http://basharatspace.blogspot.com/
  • Q&A