COM Interop Gets Much Better in C# 4.0

he first article in this series on C#’s new features looked at the language’s new support for dynamic lookup and for named and optional parameters in C#. This article and the concluding article in this series cover the enhanced COM Interop features and support for variance in C# 4.0.

Enhanced COM Interop Features

C# 4.0 provides much improved support for COM interoperability, making it far easier to call COM objects from your .NET code. You need fewer typecasts, the ref keyword is no longer required, and you no longer have to depend on Primary Interop Assemblies, or PIAs. In essence, C# 4.0 provides a lot of new features that are specifically targeted to make your life easier when working with COM interop. The new dynamic lookup and support for named and optional parameters discussed in the previous article help improve the experience of interoperating with COM APIs such as the Office Automation APIs.

For example, here’s the pre-4.0 C# code you need to write to open a Word document:

using Word = Microsoft.Office.Interop.Word;namespace COMInterop{   class Program   {      static void Main(string[] args)      {         Word.Application wordApplication =             new Word.Application() { Visible = true };         object missingValue = System.Reflection.Missing.Value;         object readOnlyValue = true;         object fileName = @"C:\DevX.docx";         wordApplication.Documents.Open(ref fileName, ref             missingValue, ref readOnlyValue,            ref missingValue, ref missingValue,             ref missingValue, ref missingValue,             ref missingValue, ref missingValue,            ref missingValue, ref missingValue,            ref missingValue, ref missingValue,            ref missingValue,ref missingValue);      }   }}

In the Open call in the last line, you can see that you need to pass a number of optional parameters just to satisfy the method call. With the introduction of optional and named parameters in C# 4.0, you can do the same with much less code.

Here’s the code you can use to open a word document in C# 4.0:

using Word = Microsoft.Office.Interop.Word;namespace COMInterop{   class Program   {      static void Main(string[] args)      {         Word.Application wordApplication = new             Word.Application() {Visible = true};            wordApplication.Documents.Open(@"C:\DevX.docx",             ReadOnly: true);      }   }}

Improved Performance

PIAs are generated from the COM interfaces. You can use such assemblies in your application’s code to interoperate with COM objects in a strongly typed manner; however, they’re heavy, consume a huge amount of memory, and can slow down the application’s performance considerably. Instead, the interop assembly generated by compiling the preceding code would contain only the interop code actually used by your application, which reduces the size of your assembly drastically and improves the application’s performance.

Dynamic Import

The majority of the COM methods accept and return variant types. These are represented in the PIAs as objects. So, when you use these methods, you need to use appropriate casts. With C# 4.0 however, you use the dynamic keyword instead of object in the method signatures of the COM methods. Therefore, you can now call such methods without having to cast the types as you did earlier.

Consider the following code where you need to use casts to set a value in a particular cell in an Excel document.

 ((Excel.Range)excelObj.Cells[5, 5]).Value =    "This is sample text";

The preceding code uses casts, but in C# 4.0, you can eliminate the casts?thanks to the dynamic keyword! Here’s a new way to achieve the same result:

excelObj.Cells[5, 5].Value = "This is sample text";

As a more complete example, here’s some typical C# 3.x code to save an Excel document in C#.

using Excel = Microsoft.Office.Interop.Excel;namespace COMInterop{   class Program   {      static void Main(string[] args)      {         var excelApplication = new Excel.Application();         excelApplication.Visible = true;         dynamic excelWorkBook =             excelApplication.Workbooks.Add(            System.Reflection.Missing.Value);         Excel.Worksheet wkSheetData = (            Excel.Worksheet)excelWorkBook.ActiveSheet;         excelWorkBook.SaveAs("Testfile.xls",             System.Reflection.Missing.Value,             System.Reflection.Missing.Value,            System.Reflection.Missing.Value,             System.Reflection.Missing.Value,             System.Reflection.Missing.Value,            Excel.XlSaveAsAccessMode.xlShared,             System.Reflection.Missing.Value,             System.Reflection.Missing.Value,            System.Reflection.Missing.Value,             System.Reflection.Missing.Value,             System.Reflection.Missing.Value);      }   }}

In C# 4.0, you no longer need to use the missing values and explicit casts shown above. Here’s the same functionality in C# 4.0 without the usage of explicit casts and missing values:

using Excel = Microsoft.Office.Interop.Excel;namespace COMInterop{   class Program   {      static void Main(string[] args)      {         var excelApplication = new Excel.Application();         excelApplication.Visible = true;         dynamic excelWorkBook = excelApplication.Workbooks.Add();         Excel.Worksheet wkSheetData = excelWorkBook.ActiveSheet;          excelWorkBook.SaveAs(            "Testfile.xls",            AccessMode: Excel.XlSaveAsAccessMode.xlShared);      }   }}
Author’s Note: Note that COM has an entirely different programming model than managed code. To call COM methods, the C# compiler allowed you to pass parameters by value and would generate temporary variables to hold those values. The variables were discarded when the method completed.

Support for Variance

With C# 4.0, you can specify in (input only) and out (return only) parameters on generic types. These parameters can then be passed as only input parameters or used only as return values for such types.

Support for variance in C# 4.0 can be twofold: covariance and contravariance. The terms invariance, covariance and contravariance deserve a bit of explanation. Bill Wagner writes: “A return value or parameter is invariant if you must use the exact match of the formal type name. A parameter is covariant if you can use a more derived type as a substitute for the formal parameter type. A return value is contravariant if you can assign the return type to a variable of a less derived type than the formal parameter.”

Author’s Note: I won’t cover invariant parameters any further here?you’re already more than familiar with those from earlier versions of C#.

Covariance

Covariance is easier to understand with a simple example. Note that string is a specific type, whereas object is a generic type. So, string is covariant to object. Now, let?s see how .NET 4.0 supports covariance. The interface IEnumerable is defined in .NET 4.0 as shown below:

public interface IEnumerable : IEnumerable{   IEnumerator GetEnumerator();}public interface IEnumerator : IEnumerator{  bool MoveNext();  T Current { get; }}

In earlier versions of C#, an IEnumerable wasn?t an IEnumerable. Notice the out parameter in the preceding IEnumerator definition, which indicates that generic T can occur only in the output position; otherwise, the compiler will report an error. The interface is covariant in T meaning that IEnumerable

is also IEnumerable provided P is derived from Q. So, a sequence of strings is also a sequence of objects. Hence, the following statement is perfectly valid:

IEnumerable someObj = new List();

The next example illustrates how you can make use of covariance in C# 4.0:

namespace Test{   class Base    {      //Methods and Properties of the Base Class   }   class Derived : Base    {       //Methods and Properties of the Derived Class   }   class Program   {      delegate T TestFunction();      static void Main(string[] args)      {         TestFunction derivedObj = () => new Derived();         TestFunction baseObj = derivedObj;      }   }}

Contravariance

Type parameters in generic interfaces in C# 4.0 can have an in modifier that allows them to occur in input positions only, for example:

public interface IComparer{  public int Compare(T left, T right);}

So, a comparer that can compare objects can compare strings as well. This is called contravariance. A good example of contravariance is the Equals() method or the CompareTo() method. If you have a method that can compare two instances of a base class, you can use the same method to compare two instances of a derived class as well. You can easily store the result of any method calls in an instance of type object, because method return types in C# are contravariant.

Here’s a contravariant counterpart of the preceding example:

namespace Test{   class Base    {      }   class Derived : Base    {      }   class Program   {      delegate void TestDelegate(T a);      static void Main(string[] args)      {         TestDelegate baseObj = (obj) => {             System.Console.WriteLine(obj); };         TestDelegate derivedObj = baseObj;      }   }}
Author’s Note: Type variance works only on interfaces and delegate types. Variance can be applied only if there is a reference conversion between the type arguments. So, IEnumerable is not an IEnumerable because int is a value type and object is a reference type. In other words, conversion of an integer to an object type is a boxing conversion and not a reference conversion?and therefore is not an example of variance.

As you can see, C# 4.0’s new features make working with Primary Interop Assemblies much more pleasant. The support for optional parameters means you don’t have to explicitly pass “missing” values to functions in place of optional parameters you either don’t have or don’t need. The support for named parameters means you don’t have to pass values in a specific order (as long as you use the names), and the support for variance eliminates many of the tedious and error-prone casts that were formerly required. All in all, these are welcome and useful changes.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

your company's audio

4 Areas of Your Company Where Your Audio Really Matters

Your company probably relies on audio more than you realize. Whether you’re creating a spoken text message to a colleague or giving a speech, you want your audio to shine. Otherwise, you could cause avoidable friction points and potentially hurt your brand reputation. For example, let’s say you create a

chrome os developer mode

How to Turn on Chrome OS Developer Mode

Google’s Chrome OS is a popular operating system that is widely used on Chromebooks and other devices. While it is designed to be simple and user-friendly, there are times when users may want to access additional features and functionality. One way to do this is by turning on Chrome OS

homes in the real estate industry

Exploring the Latest Tech Trends Impacting the Real Estate Industry

The real estate industry is changing thanks to the newest technological advancements. These new developments — from blockchain and AI to virtual reality and 3D printing — are poised to change how we buy and sell homes. Real estate brokers, buyers, sellers, wholesale real estate professionals, fix and flippers, and beyond may

©2023 Copyright DevX - All Rights Reserved. Registration or use of this site constitutes acceptance of our Terms of Service and Privacy Policy.

Sitemap