C# 4.0 and Beyond


Published on

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • C# 1.0 brought us managed code. C# 2.0 introduced generics. C# 3.0 introduced LINQ, which has helped to incorporate a lot of functional programming features into the language and solve some of the dissonance between the language and relational data. Finally, today, we’ll discuss what is coming up in C# 4.0, namely dynamic programming.
  • There are several trends in the industry that have shaped this release of C#. The first is a movement toward more declarative styles of programming, such as XAML, CSS, HTML and other markup languages. Dynamic languages such as Python, Ruby, Lua, and even JavaScript can be seen in practice from the World Wide Web to the World of Warcraft. And with the increase of multi-core processors, concurrency is becoming more important, especially from the perspective of what programming languages should support.
  • When we write code in the imperative style that the industry has been entrenched in for 40 years, we write (of course) what we want done, but in excruciating detail HOW we want it done. In a sense, we overspecify the solution in imperative style. This can create optimization problems and side effects, because the compiler has no choice but to execute step-by-step. However, if you use something like LINQ or another declarative style, you can say things in a more abstract sense such as “order by” or “group by.” That gives the compiler a much better chance of optimzing the code better, or even being able to execute it in parallel. This helps to push languages, including C#, in the direction of supporting more declarative features.
  • Dynamic vs static is an argument that has been around since programming languages were first born. While each paradigm has its own strengths and weaknesses, ideally you can borrow from both buckets to create something great.
  • Writing parallel code is hard. Moore’s Law has allowed us to largely ignore it, because the clock speed has simply increased over time. However, that clock speed has leveled out now (around 2.5 GHz) and instead of scaling up the speed, engineers are adding more cores. Unfortunately, there’s no magic bullet for programmers to write concurrent applications. You have to really sit down and think about how to write concurrent applications for multicore processors. The multicore trend presents a lot of interesting challenges, especially since traditionally we think of multiprocessing as the same as multithreading, where you split up work among threads on one processor. Now, we are talking about running discrete tasks on separate cores, executing tasks in parallel.You might have heard about Parallel Extensions for .NET. These extensions will allow you to write code that, through the use of lambda expressions, translates to code that will execute in parallel. This offers a glimpse into where C# is headed down the road, as well.
  • To VB and C# users, co-evolution means:Cooperation – Knowledge & technology transfer between the two teamsA little bit of rivalryInnovations in one language inevitably turn up in the other. C# introduced VB concepts such as: 1st class enumerations, properties, events. Dynamic binding, optional parameters, named arguments have all been used in VB for a long time, and now C# has the same luxury.Likewise, VB 8.0 introduced many concepts initially implemented in C#, such as overloaded operators, unsigned types, and generics. VB 9.0 brought LINQ, which was the result of quite a bit of cooperation between the C# and VB teams.However, users of VB and C# have a storied history of “sibling rivalry.” Invariably, with every new release, one language gets a cool new toy, and the other is left asking, “Where’s my toy?”For example: Nullable types in C# 2.0 (not implemented til VB 9.0), automatic properties in C# 3.0 (not implemented til VB 10).The vision is to have a tight cooperation between both teams to commit to developers that capabilities will show up in both languages at pretty much the same time. The next release of these languages brings us a step closer to that vision.
  • C# 1.0 brought us managed code. C# 2.0 introduced generics. C# 3.0 introduced LINQ, which has helped to incorporate a lot of functional programming features into the language and solve some of the dissonance between the language and relational data. Finally, today, we’ll discuss what is coming up in C# 4.0, namely dynamic programming.
  • Where the CLR is a common platform for statically typed objects, the DLR unifies dynamic programming on top of .NET. The core infrastructure in the DLR includes Expression Trees (such as LINQ), dynamic dispatch to different binders, and call site caching to avoid having to resolve to the same location more than once. IronPython and IronRuby already support the DLR. Now, with C# 4.0 and the next release of VB, these languages can target the DLR as well.The way the DLR interfaces with other platforms is via binders. There is an object binder that maps to statically typed .NET objects. There is a JavaScript binder that allows us to bind directly to javascript in Silverlight applications (and bypass the COM-stile invocation). Similar binders exist for Python, for Ruby, and also for the Office object model.
  • How things used to look, with multiple overloads
  • Now, with optional and named params
  • Getting rid of the NASTY style of COM interop thanks to optional & named arguments and the Office library
  • Code now looks the way it was intended to look. There is now special support for indexed properties in COM objects. You can omit the ‘ref’ keyword in some cases. One feature (which can be enabled or disabled) is an automatic mapping from a static object type to a dynamic type. Another feature is No PIA (Primary Interop Assembly). So when you run the final app, you don’t need that primary assembly at all. Those types are embedded into the app now.
  • .NET arrays are co-variant, which means you can pass a string array as a less-derived object array. However, .NET arrays are not *safely* covariant. It will compile, but it will fail at runtime. For arrays of reference types, every assignment has a dynamic type check that checks what you are assigning is the same type as the actual array. Now if we had written this as using Generics, this would have failed at compile time. Until now, C# generics have been invariant, meaning those two types are not compatible. But C# 4.0 supports safe co- and contra-variance.It’s safe because IEnumerable is a read-only interface, there is no way to put new things in. Therefore, it’s safely co-variant.
  • Out: T gets restricted in output positions only (such as the result of a method call, result of a method accessor). T couldn’t be a parameter, because that would initiate dynamic type checking.So when things are co-variant, they can be treated as less derived.In the case of contra-variance, T is marked as contra-variant via the ‘in’ keyword. Contra-variant things can be treated as more derived.
  • Variance is restricted to interfaces. Technical term for our implementation is “statically checked definition site variance.”Just like arrays, value types are always invariant. Just as an int array is not an object array, an IEnumerable of int cannot be treated as an IEnumerable<object>.
  • Now that C# 4.0 supports variance, some of the existing interfaces and delegates have been decorated with the appropriated variance annotations. While it’s interesting on a technical level, what this really does is allow you to do things in code that you previously wondered why you couldn’t do.
  • Meta-programming is used all over the place, from script environments, to dynamic code generation (entity framework, LINQ to SQL, Reflection.Emit). These technologies can be kind of painful to use. The C# compiler, going forward, is heading towards managed code. Currently it’s written in C++ (because you have to write the compiler to get the platform, of course). It’s a very classical compiler; source file goes in, assembly comes out. But it’s a black box.Going forward, we want to open up that box and give people access to cool things like meta-programming, REPL loops, etc. The possibilities here would be to embed C# code directly in things like workflow documents or domain-specific languages, using C# as a scripting language in some host environment, and more.
  • C# 4.0 and Beyond

    1. 1. C# 4.0, and Beyond<br />Chris Koenig<br />Developer Evangelist<br />Microsoft Corporation<br />chris.koenig@microsoft.com<br />http://chriskoenig.net<br />@chriskoenig<br />
    2. 2. The Evolution of C#<br />C# 3.0<br />Language Integrated Query<br />C# 2.0<br />Generics<br />C# 1.0<br />Managed Code<br />
    3. 3. Trends<br />
    4. 4. Declarative Programming<br />What<br />How<br />Imperative<br />Declarative<br />
    5. 5. Dynamic vs. Static<br />
    6. 6. Concurrent<br />
    7. 7. Co-Evolution<br />
    8. 8. The Evolution of C#<br />C# 4.0<br />Dynamic Programming<br />C# 3.0<br />Language Integrated Query<br />C# 2.0<br />Generics<br />C# 1.0<br />Managed Code<br />
    9. 9. <ul><li>Dynamically Typed Objects
    10. 10. Optional and Named Parameters
    11. 11. Improved COM Interoperability
    12. 12. Co- and Contra-variance</li></ul>C# 4.0 Language Innovations<br />
    13. 13. .NET Dynamic Programming<br />IronPython<br />IronRuby<br />C#<br />VB.NET<br />Others…<br />Dynamic Language Runtime<br />Expression Trees<br />Dynamic Dispatch<br />Call Site Caching<br />PythonBinder<br />RubyBinder<br />COMBinder<br />JavaScriptBinder<br />ObjectBinder<br />
    14. 14. Dynamically Typed Objects<br />Calculator calc = GetCalculator();<br />int sum = calc.Add(10, 20);<br />object calc = GetCalculator();<br />TypecalcType = calc.GetType();<br />object res = calcType.InvokeMember(&quot;Add&quot;,<br />BindingFlags.InvokeMethod, null,<br />newobject[] { 10, 20 });<br />int sum = Convert.ToInt32(res);<br />ScriptObject calc = GetCalculator();<br />object res = calc.Invoke(&quot;Add&quot;, 10, 20);<br />int sum = Convert.ToInt32(res);<br />Statically typed to be dynamic<br />dynamic calc = GetCalculator();<br />int sum = calc.Add(10, 20);<br />Dynamic method invocation<br />Dynamic conversion<br />
    15. 15. Dynamic überalles?<br />
    16. 16. Dynamically Typed Objects<br />Compile-time typedynamic<br />Run-time typeSystem.Int32<br />dynamic x = 1;<br />dynamic y = &quot;Hello&quot;;<br />dynamic z = newList&lt;int&gt; { 1, 2, 3 };<br />When operand(s) are dynamic…<br /><ul><li> Member selection deferred to run-time
    17. 17. At run-time, actual type(s) substituted for dynamic
    18. 18. Static result type of operation is dynamic
    19. 19. It’s just like object with dynamic semantics</li></li></ul><li>public static class Math<br />{<br /> publicstaticdecimal Abs(decimal value);<br /> publicstaticdouble Abs(double value);<br /> publicstaticfloat Abs(float value);<br /> publicstaticint Abs(int value);<br /> publicstaticlong Abs(long value);<br /> publicstaticsbyte Abs(sbyte value);<br /> publicstaticshort Abs(short value);<br /> ...<br />}<br />double x = 1.75;<br />double y = Math.Abs(x);<br />dynamic x = 1.75;<br />dynamic y = Math.Abs(x);<br />Dynamically Typed Objects<br />Method chosen at compile-time:double Abs(double x)<br />Method chosen at run-time: double Abs(double x)<br />Method chosen at run-time:int Abs(int x)<br />dynamic x = 2;<br />dynamic y = Math.Abs(x);<br />
    20. 20. The “dynamic” keyword<br />demo <br />
    21. 21. DynamicObject Base Class<br />publicclassDynamicObject : IDynamicMetaObjectProvider<br />{<br />protectedDynamicObject();<br />publicvirtualIEnumerable&lt;string&gt; GetDynamicMemberNames();<br />publicvirtualDynamicMetaObjectGetMetaObject(Expression parameter);<br />publicvirtualboolTryBinaryOperation(BinaryOperationBinder binder, objectarg, outobject result);<br />publicvirtualboolTryConvert(ConvertBinder binder, outobject result);<br />publicvirtualboolTryCreateInstance(CreateInstanceBinder binder, object[] args, outobject result);<br />publicvirtualboolTryDeleteIndex(DeleteIndexBinder binder, object[] indexes);<br />publicvirtualboolTryDeleteMember(DeleteMemberBinder binder);<br />publicvirtualboolTryGetIndex(GetIndexBinder binder, object[] indexes, outobject result);<br />publicvirtualboolTryGetMember(GetMemberBinder binder, outobject result);<br />publicvirtualboolTryInvoke(InvokeBinder binder, object[] args, outobject result);<br />publicvirtualboolTryInvokeMember(InvokeMemberBinder binder, object[] args, outobject result);<br />publicvirtualboolTrySetIndex(SetIndexBinder binder, object[] indexes, objectvalue);<br />publicvirtualboolTrySetMember(SetMemberBinder binder, object value);<br />publicvirtualboolTryUnaryOperation(UnaryOperationBinder binder, outobject result);<br />}<br />
    22. 22. Roll Your Own DynamicObject<br />demo <br />
    23. 23. Optional and Named Parameters<br />Primary method<br />publicStreamReaderOpenTextFile(<br /> string path,<br /> Encodingencoding,<br />booldetectEncoding,<br />intbufferSize);<br />Secondary overloads<br />publicStreamReaderOpenTextFile(<br /> string path,<br /> Encodingencoding,<br />booldetectEncoding);<br />publicStreamReaderOpenTextFile(<br /> string path,<br /> Encodingencoding);<br />publicStreamReaderOpenTextFile(<br /> string path);<br />Call primary with default values<br />
    24. 24. Optional and Named Parameters<br />Optional parameters<br />publicStreamReaderOpenTextFile(<br /> string path,<br /> Encodingencoding,<br />booldetectEncoding,<br />intbufferSize);<br />publicStreamReaderOpenTextFile(<br /> string path,<br /> Encodingencoding = null,<br />booldetectEncoding = true,<br />intbufferSize = 1024);<br />Named argument<br />OpenTextFile(&quot;foo.txt&quot;, Encoding.UTF8);<br />OpenTextFile(&quot;foo.txt&quot;, Encoding.UTF8, bufferSize: 4096);<br />Arguments evaluated in order written<br />Named arguments can appear in any order<br />Named arguments must be last<br />OpenTextFile(<br />bufferSize: 4096,<br /> path: &quot;foo.txt&quot;,<br />detectEncoding: false);<br />Non-optional must be specified<br />
    25. 25. Improved COM Interoperability<br />objectfileName = &quot;Test.docx&quot;;<br />object missing = System.Reflection.Missing.Value;<br />doc.SaveAs(reffileName,<br />ref missing, ref missing, ref missing,<br />ref missing, ref missing, ref missing,<br />ref missing, ref missing, ref missing,<br />ref missing, ref missing, ref missing,<br />ref missing, ref missing, ref missing);<br />doc.SaveAs(&quot;Test.docx&quot;);<br />
    26. 26. <ul><li>Optional and named parameters
    27. 27. Indexed properties
    28. 28. Optional “ref” modifier
    29. 29. Automatic object  dynamic mapping
    30. 30. Interop type embedding (“No PIA”)</li></ul>Improved COM Interoperability<br />
    31. 31. Improved COM Interoperability<br />demo <br />
    32. 32. Co- and Contra-variance<br />.NET arrays are co-variant<br />string[] strings = GetStringArray();<br />Process(strings);<br />…but not safelyco-variant<br />void Process(object[] objects) { … }<br />void Process(object[] objects) {<br /> objects[0] = &quot;Hello&quot;; // Ok<br /> objects[1] = newButton(); // Exception!<br />}<br />Until now, C# generics have been invariant<br />List&lt;string&gt; strings = GetStringList();<br />Process(strings);<br />C# 4.0 supports safe co- and contra-variance<br />void Process(IEnumerable&lt;object&gt; objects) { … }<br />void Process(IEnumerable&lt;object&gt; objects) {<br />// IEnumerable&lt;T&gt; is read-only and<br />// therefore safely co-variant<br />}<br />
    33. 33. Safe Co- and Contra-variance<br />publicinterfaceIEnumerable&lt;T&gt;<br />{<br />IEnumerator&lt;T&gt; GetEnumerator();<br />}<br />publicinterfaceIEnumerable&lt;out T&gt;<br />{<br />IEnumerator&lt;T&gt; GetEnumerator();<br />}<br />out= Co-variantOutput positions only<br />Can be treated asless derived<br />publicinterfaceIEnumerator&lt;T&gt;<br />{<br /> T Current { get; }<br />boolMoveNext();<br />}<br />publicinterfaceIEnumerator&lt;out T&gt;<br />{<br /> T Current { get; }<br />boolMoveNext();<br />}<br />IEnumerable&lt;string&gt; strings = GetStrings();<br />IEnumerable&lt;object&gt; objects = strings;<br />in= Contra-variantInput positions only<br />publicinterfaceIComparer&lt;T&gt;<br />{<br />int Compare(T x, T y);<br />}<br />publicinterfaceIComparer&lt;in T&gt;<br />{<br />int Compare(T x, T y);<br />}<br />Can be treated asmore derived<br />IComparer&lt;object&gt; objComp = GetComparer();<br />IComparer&lt;string&gt; strComp = objComp;<br />
    34. 34. Variance in C# 4.0<br />Supported for interface and delegate types<br />“Statically checked definition-site variance”<br />Value types are always invariant<br />IEnumerable&lt;int&gt; is not IEnumerable&lt;object&gt;<br />Similar to existing rules for arrays<br />ref and out parameters need invariant type<br />
    35. 35. Variance in .NET Framework 4.0<br />Interfaces<br />System.Collections.Generic.IEnumerable&lt;out T&gt;<br />System.Collections.Generic.IEnumerator&lt;out T&gt;<br />System.Linq.IQueryable&lt;out T&gt;<br />System.Collections.Generic.IComparer&lt;in T&gt;<br />System.Collections.Generic.IEqualityComparer&lt;in T&gt;<br />System.IComparable&lt;in T&gt;<br />Delegates<br />System.Func&lt;in T, …, out R&gt;<br />System.Action&lt;in T, …&gt;<br />System.Predicate&lt;in T&gt;<br />System.Comparison&lt;in T&gt;<br />System.EventHandler&lt;in T&gt;<br />
    36. 36. The Evolution of C#<br />C# 4.0<br />Dynamic Programming<br />C# 3.0<br />Language Integrated Query<br />C# 2.0<br />Generics<br />C# 1.0<br />Managed Code<br />
    37. 37. Compiler as a Service<br />Class<br />Meta-programming<br />Read-Eval-Print Loop<br />public<br />Foo<br />Field<br />Language<br />Object Model<br />DSL Embedding<br />private<br />X<br />string<br />Compiler<br />Compiler<br />SourceFile<br />.NET Assembly<br />Source code<br />Source code<br />Source code<br />Source code<br />
    38. 38. © 2009 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.<br />The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.<br />