2. The Evolution of C# C# 4.0 Dynamic Programming C# 3.0 Language Integrated Query Ruby On Rails 2.0 C# 2.0 Generics Java EE 5, Ruby On Rails 1.0 C# 1.0 Managed Code Mono announced, J2SE 1.4
3. C# 4.0 Language Innovations Dynamically Typed Objects Optional and Named Parameters Improved COM Interoperability Co- and Contra-variance
4. Why Dynamic? There is a lot of interest in accessing the highly dynamic object model of HTML DOM COM is heavily used and inter op code could be easier to read and write Dynamic languages are becoming increasingly popular We need unified way to work with all of the above
5. .NET Dynamic Programming Architecture IronPython IronRuby C# VB.NET Others… Dynamic Language Runtime Expression Trees Dynamic Dispatch Call Site Caching PythonBinder RubyBinder COMBinder JavaScriptBinder ObjectBinder
6. Dynamically Typed Objects Calculator calc = GetCalculator(); int sum = calc.Add(10, 20); .NET object object calc = GetCalculator(); TypecalcType = calc.GetType(); object res = calcType.InvokeMember("Add", BindingFlags.InvokeMethod, null, newobject[] { 10, 20 }); int sum = Convert.ToInt32(res); Dynamic Language object ScriptObject calc = GetCalculator(); object res = calc.Invoke("Add", 10, 20); int sum = Convert.ToInt32(res); Statically typed to be dynamic dynamic calc = GetCalculator(); int sum = calc.Add(10, 20); Dynamic method invocation Dynamic conversion
7. dynamic calc = GetCalculator(); int sum = calc.Add(10, 20); Under the cover dynamic is a new type only in the compiler Encoded in IL as object + dynamic attribute Operations on a dynamic variable become CallSites, objects “interpreted” by the DLR member selection deferred to run-time cache the result of the bindings the return type of a dynamic operation is dynamic Support all types of operations on dynamic method call, property access, indexer access, operators, conversions
8. dynamici = 3; Math.Abs(i); Under the cover For binding calls to .NET types there is a runtime C# binder Does overload resolution using runtime types for dynamic arguments Overload resolution changed to accommodate dynamic method calls Dynamic arguments are treated as wildcards for overload resolution
9. Under the cover When dose the compiler dispatch dynamically? if the receiver of the call is dynamic OR if any of the arguments to the call are typed dynamic We can dynamically dispatch to static methods
10. Under the cover dynamic d = newDynamicObject(); d.Foo(); You can now write your own object that does dynamic dispatch just implement IDynamicObject The C# runtime binder can function as a fallback for calls to dynamic objects if your object is “hybrid” and some of the methods are dynamically dispatched and some are regular methods the C# semantics will be applied if the Object cannot itself resolve a call
12. Improved COM interoperability Automatic object -> dynamic mapping Optional and named parameters Optional “ref” modifier Interop type embedding (“No PIA”) Indexed properties
13. object -> dynamic mapping We need to cast ((Excel.Range)xl.Cells[1,1]).Value2 = “ID”; xl.Cells[1,1].Value2 = “ID”; When the return type of a COM call is object you are forced to cast to a known type Making the code harder to understand If the return type is dynamic, you can continue to “dot” on the return type If you typed something wrong the compiler won’t tell you
14. Optional and named parameters xlChart.ChartWizard(cellRange.CurrentRegion, Constants.xl3DBar, Type.Missing, Excel.XlRowCol.xlColumns, 1, 2, false, xlSheet.Name, Type.Missing, Type.Missing, Type.Missing); Non-optional must be specified xlChart.ChartWizard(cellRange.CurrentRegion, Constants.xl3DBar, PlotBy: Excel.XlRowCol.xlColumns, SeriesLabels: 2, CategoryLabels: 1, HasLegend: false, Title: xlSheet.Name); Arguments evaluated in order written Named arguments can appear in any order
17. Under the cover The default value for a parameter is encoded with DefaultParameterValue attribute The compiler inserts that value if a value is not specified for that parameter If a default value is not specified we will use default (type) For COM the compiler will pass in Type.Missing The compiler will rearrange the specified named parameters and then apply overload resolution
18. Under the cover You can override methods that declare optional parameters The value of the parameter comes from the static type you used to call the method You can rename a parameter in an override The compiler will use the name found in the static type you used to call the method “Omit ref” only works for COM objects The compiler creates a variable to store the value you specified and passes the created variable “by ref” to COM
19. Co- and Contra-variance .NET arrays are co-variant string[] strings = GetStringArray(); Process(strings); …but not safelyco-variant void Process(object[] objects) { … } void Process(object[] objects) { objects[0] = "Hello"; // Ok objects[1] = newButton(); // Exception! } Until now, C# generics have been invariant List<string> strings = GetStringList(); Process(strings); C# 4.0 supports safe co- and contra-variance void Process(IEnumerable<object> objects) { … } void Process(IEnumerable<object> objects) { // IEnumerable<T> is read-only and // therefore safely co-variant }
20. Safe Co- and Contra-variance publicinterfaceIEnumerable<T> { IEnumerator<T> GetEnumerator(); } publicinterfaceIEnumerable<out T> { IEnumerator<T> GetEnumerator(); } out= Co-variantOutput positions only Can be treated asless derived publicinterfaceIEnumerator<T> { T Current { get; } boolMoveNext(); } publicinterfaceIEnumerator<out T> { T Current { get; } boolMoveNext(); } IEnumerable<string> strings = GetStrings(); IEnumerable<object> objects = strings; in= Contra-variantInput positions only publicinterfaceIComparer<T> { int Compare(T x, T y); } publicinterfaceIComparer<in T> { int Compare(T x, T y); } Can be treated asmore derived IComparer<object> objComp = GetComparer(); IComparer<string> strComp = objComp;
21. Variance in C# 4.0 supported for interface and delegate types statically checked definition site variance value types are always invariant IEnumerable<int> is not IEnumerable<object> similar to existing rules for arrays ref and out parameters need invariant type
22. Summary We have a new type called dynamic Calls that involve variables of type dynamic are treated differently by compiler We package extra information about the call Calls can be: method calls, property access, indexer call, operator call There is a C# runtime binder to interpret the information (at runtime) It uses the runtime type for all dynamic arguments It uses the compile time type for all other arguments
23. How dynamic works CLR Expression Tree COM Binder Exe IronPython Binder Compile Run Bind call Dynamic Call Delegate DLR C# Runtime Binder Cache …
24. Review What is the dynamic type? There is no dynamic type . There is only object. What operations are supported? A variable of type dynamic is assumed to support any kind of operation (method call, property access, indexer call and operator call) How is the information about the call stored? Using CallSites objects the compiler packages data about the call
25. What does a CallSite contain? Information about the call being made What type of call (method call, property access, etc) The name of the member The context of the call The type arguments for the call Information about the parameter and return types Is it a constant? Is it passed by-ref, etc.
26. Dynamic FAQ When do you go dynamic? When the target of the call OR any of the call arguments are dynamic What is the return type of a dynamic call? It is dynamic in most case What about conversions and constructors? They are dispatched at runtime, but their return type is known at compile time
27. Dynamic FAQ What about private methods? Information about the context of call is embedded in the CallSite allowing the Binder to “do the right thing” Calling a method off a non-dynamic target with dynamic arguments It works as expected We embed the type of all the receiver in the CallSite Can dynamic “cross” assembly boundaries? Yes, we decorate any dynamic parameter or return type with a DynamicAttribute It works for generic types constructed with dynamic as well
28. Dynamic FAQ Can I use named and optional with dynamic? Yes And also Co & Contra variance Where can’t I use dynamic? Lambda expressions LINQ Can’t use dynamic with method groups Throw or catch statements
29. Quiz! classBase { publicvirtualvoid Foo(int x = 4, int y = 5) { Console.WriteLine("x:{0}, y:{1}", x, y); } } classDerived : Base { publicoverridevoid Foo(int y = 4, int x = 5) { Console.WriteLine("x:{0}, y:{1}", x, y); } } classProgram { staticvoid Main(string[] args) { Base b = newDerived(); b.Foo(x: 4, y: 5); } } Output: x:4, y:5 x:5, y:4 x:4, y:4 x:5, y:5 None of the above Output: x:4, y:5 x:5, y:4 x:4, y:4 x:5, y:5 None of the above