Welcome to MSDN Blogs Sign in | Join | Help

Simplifying enumeration of Office object model collections with Linq and Extension methods

I found an interesting post on Deborah's Developer MindScape  (via Greg’s blog )and wanted to share a modification of the technique that can simplify the use of Office object models in C# and VB. I use this heavily in my VisioAutomation library.

 

First, let’s look at the the Deborah’s original solution :

var query = from d in Wd.Documents.Cast<Word.Document>()
            select d.Name;

SIMPLIFYING WITH EXTENSION METHODS

This works fine. Through the use of extension methods we can make this even more succinct. The core pain to address is the need to re-enter the type (“Word.Document”) when it is already clear that is the only possible kind of object in the collection

A simple extension method makes this even easier:

var query = from d in Wd.Documents.AsEnumerable()
            select d.Name;

The extension method that achieved this is trivial

public static class WordExtensions
{
    public static IEnumerable<Word.Document> AsEnumerable(this Word.Documents docs)
    {
        return docs.Cast<Word.Document>();
    }

}

SOURCE CODE

The full source code is below ( you can get the entire project from my SkyDrive)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Word = Mi2crosoft.Office.Interop.Word;

namespace DemoOfficeCollectionsIEnumerable
{
    class Program
    {

        static void Main(string[] args)
        {
            before();
            after_with_an_extension_method();

        }

        public static void before()
        {

            // Start Word and get Application object
            var Wd = new Word.Application();

            // Define documents
            var doc1 = Wd.Documents.AddEmptyDoc();
            var doc2 = Wd.Documents.AddEmptyDoc();

            // Use Linq to access the document names.
            var query = from d in Wd.Documents.Cast<Word.Document>()
                        select d.Name;
            var docsnames1 = query.ToList();

            // Or use Lambda expressions
            var query2 = Wd.Documents.Cast<Word.Document>().Select(d=> d.Name);
            var docnames2 = query2.ToList();

        }

        public static void after_with_an_extension_method()
        {
            // Add to the top of the code file

            object missingValue = System.Reflection.Missing.Value;

            // Start Word and get Application object
            var Wd = new Word.Application();

            // Define documents
            var doc1 = Wd.Documents.AddEmptyDoc();
            var doc2 = Wd.Documents.AddEmptyDoc();

            // Use Linq to access the document names.
           
var query = from d in Wd.Documents.AsEnumerable()
                        select d.Name;

            var docsnames1 = query.ToList();

            // Or use Lambda expressions
            var query2 = Wd.Documents.AsEnumerable().Select(d => d.Name);
            var docnames2 = query2.ToList();

        }

    }

    public static class WordExtensions
    {
        public static IEnumerable<Word.Document> AsEnumerable(this Word.Documents docs)
        {
            return docs.Cast<Word.Document>();
        }

        public static Word.Document AddEmptyDoc(this Word.Documents docs)
        {
            object missingValue = System.Reflection.Missing.Value;
            return docs.Add(ref missingValue, ref missingValue,
                                   ref missingValue, ref missingValue);
        }
    }

}

PARTING THOUGHTS

  • I through in an extra extension method (AddEmptyDoc) and liberal use of ‘var’ to make the sample source code smaller
Published Saturday, August 15, 2009 11:29 AM by saveenr

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker