Pages

Friday, August 20, 2010

C# 4.0, .NET 4, and Visual Studio 2010

Since C# favors general-purpose language features designed to be composed with one
another, it often doesn’t make sense to describe individual new features on their own.
So rather than devoting sections or whole chapters to new features, we cover them in
context, integrated appropriately with other, older language features. The section
you’re reading right now is an exception, of course, and the main reason is that we
expect people already familiar with C# 3.0 to browse through this book in bookstores
looking for our coverage of the new features. If that’s you, welcome to the book! If you
look in the Preface you’ll find a guide to what’s where in the book, including a section
just for you, describing where to find material about C# 4.0 features.
That being said, a theme unites the new language features in version 4: they support
dynamic programming, with a particular focus on making certain interoperability sce-
narios simpler. For example, consider the C# 3.0 code in Example 1-3 that uses part
of the Office object model to read the Author property from a Word document.

Example 1-3. The horrors of Office interop before C# 4.0

static void Main(string[] args)
{
var wordApp = new Microsoft.Office.Interop.Word.Application();
object fileName = @"WordFile.docx";
object missing = System.Reflection.Missing.Value;
object readOnly = true;
Microsoft.Office.Interop.Word._Document doc =
wordApp.Documents.Open(ref fileName, ref missing, ref readOnly,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing);
object docProperties = doc.BuiltInDocumentProperties;
Type docPropType = docProperties.GetType();
object authorProp = docPropType.InvokeMember("Item",
BindingFlags.Default | BindingFlags.GetProperty,
null, docProperties,
new object[] { "Author" });
Type propType = authorProp.GetType();
string authorName = propType.InvokeMember("Value",
BindingFlags.Default |BindingFlags.GetProperty,
null, authorProp,
new object[] { }).ToString();
object saveChanges = false;
doc.Close(ref saveChanges, ref missing, ref missing);
Console.WriteLine(authorName);
}

That’s some pretty horrible code—it’s hard to see what the example does because the
goal is lost in the details. The reason it is so unpleasant is that Office’s programming
model is designed for dynamic languages that can fill in a lot of the details at runtime.
C# 3.0 wasn’t able to do this, so developers were forced to do all the work by hand

Example 1-4 shows how to do exactly the same job in C# 4.0. This is a lot easier to
follow, because the code contains only the relevant details. It’s easy to see the sequence
of operations—open the document, get its properties, retrieve the Author property’s
value, and close the document. C# 4.0 is now able to fill in all the details for us, thanks
to its new dynamic language feat

Example 1-4. Office interop with C# 4.0


static void Main(string[] args)
{
var wordApp = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word._Document doc =
wordApp.Documents.Open("WordFile.docx", ReadOnly: true);
dynamic docProperties = doc.BuiltInDocumentProperties;
string authorName = docProperties["Author"].Value;
doc.Close(SaveChanges: false);
Console.WriteLine(authorName);
}


This example uses a couple of C# 4.0 features: it uses the new dynamic keyword for
runtime binding to members. It also uses the support for optional arguments. The
Open and Close methods take 16 and 3 arguments, respectively, and as you can see from
Example 1-3, you need to provide all of them in C# 3.0. But Example 1-4 has only
provided values for the arguments it wants to set to something other than the default.
Besides using these two new features, a project containing this code would usually be
built using a third new interop feature called no-PIA. There’s nothing to see in the
preceding example, because when you enable no-PIA in a C# project, you do not need
to modify your code—no-PIA is essentially a deployment feature. In C# 3.0, you had
to install special support libraries called primary interop assemblies (PIAs) on the target
machine to be able to use COM APIs such as Office automation, but in C# 4.0 you no
longer have to do this. You still need these PIAs on your development machine, but the
C# compiler can extract the information your code requires, and copy it into your
application. This saves you from deploying PIAs to the target machine, hence the name,
“no-PIA”.
While these new language features are particularly well suited to COM automation
interop scenarios, they can be used anywhere. (The “no-PIA” feature is narrower, but
it’s really part of the .NET runtime rather than a C# language feature.)

No comments:

Post a Comment