CHAPTER 3
39
Language and Dynamic
Changes
There are some welcome changes to C# and VB.NET, and major enhancements to the Common
Language Runtime(CLR) and Base Class Library (BCL) in .NET 4.0. I have separated these changes into
two chapters:language (this chapter) and CLR and BCL (Chapter 4), although there is of course some
overlap.
In this chapter I will be covering the following:
• Future co-evolution of VB and C#
• Changes to C# and VB
• Improved COM interoperability
• Variance
• Dynamic code
• F#
Future Co-evolution of VB and C#
All .NET languages compile to the same IL code, so there is really no reason a feature should be present
in one language and not another. Traditionally, C# got most of the new features, but not anymore.
Microsoft has stated that it will now aim to ensure that VB and C# contain the same functionality.
VB.NET and C# will be kept in sync like an elastic band: when a new feature is introduced in one
language, it will be brought into the other language in the next release pinging the two into line. There
will of course continue to be style differences between the languages, so don’t expect to see semi-colons
appearing in VB because that would be very silly.
This release tries to sync the two languages, fixes an old constraint, and introduces some great
dynamic functionality. No longer will VB.NET developers miss out on anonymous methods and C#
developers will now benefit from named and optional parameters.
C# Enhancements
C# 2010 introduces two useful features that have been present in VB for a long time: optional and named
parameters (technically two separate features but often found together).
CHAPTER 3 LANGUAGE AND DYNAMIC CHANGES
40
Named and Optional Parameters
Named parameters allow you to pass parameters into a function in any order and are near essential
when using C#’s other new feature: optional parameters. To use a named parameter, simply specify the
parameter name followed by a colon and then the value you are passing into a function. The following
code illustrates passing the value 1 to a method’s Copies parameter, COLOR to the ColorMode parameter,
and readme.txt to DocumentName :
Print(Copies:1,ColorMode:"COLOR",DocumentName:"readme.txt");
static void Print(string ColorMode, string DocumentName, int Copies)
{ }
Optional parameters are created in C# by specifying a default value and must appear after required
parameters:
static void Print(int Copies=1, string ColorMode="Color", string DocumentName="") { }
This method can then be called in a multitude of ways, some of which are shown here:
Print(1);
Print(1, "Color");
Print(1, "Color", "My doc");
Print(Copies: 1);
Print(ColorMode: "Color");
Print(DocumentName: "myDoc.txt");
Print(Copies: 1, ColorMode: "Color");
Print(Copies: 1, ColorMode: "Color", DocumentName: "myDoc.txt");
Optional parameters can make your code more readable and easier to maintain, and can reduce the
amount of typing you have to do. They also can make it easier to work with COM objects (see the
following section). For example, if we were creating a Print() method that accepts a number of different
parameters, we no longer have to overload it with a number of methods, such as:
public void Print(string DocumentName)
{
Print(DocumentName, 1, "COLOR");
}
public void Print(string DocumentName, int Copies)
{
Print(DocumentName, Copies, "COLOR");
}
public void Print(string DocumentName, int Copies, string ColorMode)
{}
Optional parameters allow us to refine this as:
public void Print(string DocumentName, int Copies=1, string ColorMode="COLOR")
{ }
CHAPTER 3 LANGUAGE AND DYNAMIC CHANGES
41
Rules (Non-Optional)
There some rules you need to be aware of when working with named parameters.
• Non-optional parameters must be declared first.
• Non-optional parameters must still be specified when you call a method.
• Parameters are evaluated in the order they are declared.
• If two function signatures are equally valid for your input, then the one with no
optional values is given precedence.
VB.NET Changes
Although in this book I am mainly covering C#, for completeness I will cover changes to VB.NET as well.
Line Continuation
One of the aspects of VB.NET I really hated was the line continuation character (an underscore with a
space before it). This particularly annoyed me when writing LINQ queries, because it made them less
readable and the underscore character is kind of awkward to type (okay that’s not
that
big an issue):
Dim numbers() As Integer = {1, 2, 3, 4, 5}
Dim query = from n in numbers _
Select n _
Where n>5
In .NET 4.0, in the majority of situations, this will no longer be necessary, as the compiler is now
clever enough to work out how lines will be split. This then allows the above LINQ query to be rewritten
without the underscore character:
Dim query = from n in numbers
Select n
Where n>5
You can of course continue to use the line continuation character in your code so you will not have
to do any modifications to existing projects. You may also need to use it in the unlikely situation the
compiler cannot infer where a line break exists.
Inferred Line Continuation Rules
According to Microsoft, the inferred line continuation works in the following situations:
• After an attribute.
• After a comma.
• After a dot (such as for method invocation).
• After a binary operator.
• After a LINQ query clause.
CHAPTER 3 LANGUAGE AND DYNAMIC CHANGES
42
• After a (, {, or <%=.
• Before a ), }, or %>.
Anonymous Method Support
Anonymous methods allow you to declare an inline function and can make code more readable. This
can be done as follows (note how we don’t need line continuation underscores):
Dim add = Function(x as integer, y as integer)
Return x+y
End function
Auto-Implemented Properties
It is very common to need to create private variables with public accessor methods. In VB.NET you
probably have written something like the following (although bet you haven’t had the need to create a
Tiger class):
Public Class Tiger
Private _Name As String
Property Name() As String
Get
Return _Name
End Get
Set(ByVal Name As String)
_Name = Name
End Set
End Property
End Class
You can now use the following syntax to get the compiler to generate a private backing field like in
C#:
Public Class AdvancedTiger
Property Name() As String
End Class
The old syntax is of course still supported.
Collection Initializes/From Keyword
Adding items to a collection in VB was previously slightly tedious, and would be done with code such as
the following:
CHAPTER 3 LANGUAGE AND DYNAMIC CHANGES
43
Dim ThingsNotFoundInEmploymentAgents As New List(Of String)
ThingsNotFoundInEmploymentAgents.Add(“technical knowledge”)
ThingsNotFoundInEmploymentAgents.Add(“honesty”)
ThingsNotFoundInEmploymentAgents.Add(“a reflection”)
Collections can now be initialized using the following syntax with the new From keyword:
Dim TraitsNotFoundInJobAgents As New List(Of String) From {
"technical knowledge", "honesty", "a reflection"
}
Array Literals
Array literals allow the compiler to infer an array. In the following example the array will be
automatically typed as an integer:
Dim myArray = {2, 3, 5}
Personally I prefer to specify the type, as I think it makes your intention clearer, but the decision is
now yours.
New Syntax for Creating Jagged Arrays
Until this release you could not declare jagged arrays in VB.NET easily and would have to resort to code
similar to the following:
Dim firstSetOfValues() As Integer = {1, 2, 3}
Dim seondSetOfValues() As Integer = {4, 5}
Dim allValues()() As Integer = {firstSetOfValues, seondSetOfValues}
However, you can now use the following syntax:
Dim allValuesNewWay = {({"1", "2", "3"}),
({"4", "5"})}
Nullable Optional Parameters
Optional parameters can now be nullable:
Public Sub MyFunction(ByVal Val1 As String, Optional ByVal z As Integer? = Nothing)
End Sub
Easier COM Interoperability
Many of the language enhancements we have looked at so far can greatly ease working with legacy code
such as COM objects.
Let’s look in more detail as to by adapting an example from Scott Hansleman’s blog (www.hanselman.
com/blog/CLRAndDLRAndBCLOhMyWhirlwindTourAroundNET4AndVisualStudio2010Beta1.aspx).
CHAPTER 3 LANGUAGE AND DYNAMIC CHANGES
44
In Scott’s example, the Microsoft Office API is used to open an existing text file. To see this example,
add the following code and a reference to Microsoft.Office.Interop.Word then take a look at the
intellisense for the Open() method (see Figure 3-1: eek!):
using Microsoft.Office.Interop.Word.
var WordApplication =
new Microsoft.Office.Interop.Word.Application();WordApplication.Visible = true;
object missing = System.Reflection.Missing.Value;
object file =@"c:\test.txt";
object visible = true;
object readOnly = false;
Document aDoc = WordApplication.Documents.Open(
ref file,ref missing,ref readOnly,ref missing,
ref missing,ref missing,ref missing,ref missing,
ref missing,ref missing,ref missing,ref visible,
ref missing,ref missing,ref missing,ref missing);
Figure 3-1. Working with Microsoft Office Interop is fun honest
CHAPTER 3 LANGUAGE AND DYNAMIC CHANGES
45
.NET optional and named parameters make this much easier:
var betterWay = WordApplication.Documents.Open(file, ReadOnly: true, Visible: true);
betterWay.Activate();
The new dynamic functionality (which we will look at shortly) can also make your code more
readable by allowing you to infer many casting operations. For example, the compiler can now work out
the type of object you are using (duck typing) allowing code such as
((Excel.Range) excel.Cells[1, 1]).Value2 = "Excell-ent!";
… to be rewritten as:
excel.Cells[1, 1].Value = "Excell-ent!";
Not hugely different, but much more readable.
We’re Out of PIA
Another COM-related change worth mentioning is that you no longer need PIA files. In previous
versions of Visual Studio, when a COM component was referenced, Visual Studio would create an
additional assembly to describe the COM DLL to the CLR (a PIA or Primary Interop Assembly).
Unfortunately, these PIA files could get pretty large as they described every method of the COM
object even if you were not using them. In VS2010 to stop Visual Studio generating PIA files simply set
the Embed Interop Types property to True in Solution Explorer.
Variance
Variance has changed in .NET 4.0. At the 2008 PDC Anders Hejlsberg (lead architect of C#) summarized
the changes to variance as:
(Allowing) you to do things in your code that previously you were surprised
you couldn’t do.
For those that are already comfortable with the concept of variance (stop looking so smug) here is
the short version of what has changed in .NET 4.0:
• You can now mark parameters in generic interfaces and delegates with the out
keyword to make them covariant, and with the in keyword to make them
contravariant (In and Out in VB.NET).
• The in/out keywords have been added to some commonly used generic interface
and delegate types to now enable them to support safe co- and contravariance (for
example, IEnumerable<out t> and Action<in t>).
If this means nothing to you, read on. Variance is a confusing subject, and I suspect you can have a
happy development career without it ever really affecting you. It is only applicable in a rare number of
situations.