As part of our first ALEMUG meeting I did a presentation on some of the new features in C# 4.0. Here is what I talked about.
First topic was on optional and named parameters in C#. Here is how you would define a function with optional parameters:
public static int AddTwoOrThreeOrFourNumbers(int numberOne = 0, int numberTwo = 0, int numberThree = 0, int numberFour = 0)
int returnValue = numberOne + numberTwo + numberThree + numberFour;
All you need to do to define optional parameters is to provide a default value for each one. Here is how you could call this function by providing values only for some parameters:
As you see, I only supplied two out of three parameters. All the magic is preformed by the compiler. If you look at disassembled code, you will find that call to the function actually has all three parameters defined, just the last one is zero.
Another related feature is named parameters. You can actually specify the name and the value for each parameters explicitly and out of order even:
ClassWithOptionalParameters.AddTwoOrThreeOrFourNumbers(numberOne: 1, numberFour: 4)
There are a few great uses for named / optional parameters. One is COM Interop, specifically Office Interop. Many functions in the Office take a number of optional parameter. Right now you have to specify all of them. With C# 4.0 you can specify just the ones you need. Here is an example for SavedAs:
var format = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatDocument97;
Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
var doc = word.Documents.Add();
doc.SaveAs(FileName: fileNameSaved, FileFormat: format);
In general, there are many features in C# to make Office development easier. One of them (pointed out by Jim Wooly) is No PIA – No Primary Interop Assembly distribution. To use this feature just go to properties of office interop assembly in the references window and set Embed Interop Types to True. If you do, you do not have to distribute Interop assembly!
Another features I talked about is dynamics. Here is you declare a dynamic variable:
dynamic person = ExpandoClass.GetExpando();
Looks very similar to var, doesn’t it? There is a big difference though between vars and dynamics. The key difference is the resolution time. Vars are resolved at compile time, and they are actually strongly typed in the running program. Dynamics on the other hand are resolved at run time. As a result, you can compile pretty much any code that refers to dynamics. For example, you can type
dynamic thing = GetSomeDynamicObject();
thing.SomeProperty = 1;
SomeProperty actually does not exist anywhere in the source code, it is called dynamically at run time and it will succeed as long as whatever object is returned by GetSomeDynamicObject function has this property. Very powerful feature when it comes to interacting with objects unknown at compile time. You can use it to interact with dynamic languages such Python or COM objects or even other .NET objects. Here is some code I came up with (not that I would write something like this, but it demonstrate the power of the feature) – universal sorter that can sort any collection:
public static class DynamicDemo
public static IEnumerable<dynamic> GetSortedData(IEnumerable<dynamic> initialCollection, Func<dynamic, dynamic> sortExpression)
dynamic retVal = (from one in initialCollection
Dynamics is a very powerful features, but can be easily abused. Also, anything can be dynamic, not just objects. You can also have dynamic properties and methods and their parameters.
Another related feature is ExpandoObject. This is a dynamic object that can be “expanded” at run time to contain custom properties and values:
dynamic expando = new System.Dynamic.ExpandoObject();
expando.Name = "Sergey Barskiy";
expando.Age = 18;
Seems pretty weird – I actually define the object at run time.
You can download sample solution (requires VS 2010) here.