in
Forums
Blogs
DevExpress.com
Client Center
Support Center
DevExpress Channel

Paul Kimmel's Blog

Adding Generic Anonymous Delegates to LINQ Anonymous Types

For those that know a little bit about LINQ its understood that LINQ returns Enumerable<T> objects as the result of a LINQ query. And, many of you experiment with .NET 3.5 probably know is that LINQ supports projecting new, anonymous types. A project is where you end the query with select new {} and list the fields from the originating type to be in the result type. What may not be obvious is that you can add methods to projected anonymous types. In short, this means that you can add methods to dynamically created new types.

In the example I used LINQ and Visual Studio's object relational mapping capability with LINQ to SQL to create LQIN to SQL entity types for a Customer. Using a DataContext--also generated withe LINQ to SQL--a generic delegate Func<T,T> was defined that accepted two strings and concatenated the result. This generic delegate is then assigned to a named property in the projection of the select clause of the LINQ query. When the result set is iterated over and displayed the anonymous delegate is called like any other method (refer to Listing 1).

Listing 1: Define a generic delegate and assign it to a projection to add methods to projected anonymous types.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqToSQLBlog
{
  class Program
  {
    static void Main(string[] args)
    {
      CustomersAndOrdersDataContext context =
        new CustomersAndOrdersDataContext();

      context.Log = Console.Out;
      Func<string, string, string> stringizer =
          delegate(string title, string name){
            const string mask = "{0}, {1}";
              return string.Format(mask, name, title);
           };

      var customers = from customer in context.Customers
                      select new
                      {CompanyName=customer.CompanyName,
                       ContactName=customer.ContactName,
                       ContactTitle=customer.ContactTitle,
                       Address=customer.Address,
                       City=customer.City,
                       Region=customer.Region,
                       PostalCode=customer.PostalCode,
                       Phone=customer.Phone,
                       ToContact = stringizer
                      };

      Array.ForEach(customers.ToArray(),
        c=>Console.WriteLine(c.ToContact(c.ContactTitle, c.ContactName)));
      Console.ReadLine();     

    }
  }
}

By default when you create a projection the ToString method is provided to dump all of the properties of the new type. In the example ToContact was added to display a formatted output that displays the contact name and title. You can accomplish a similar result by adding an extension method and replacing ToContact in the Console.WriteLine call with the extension method (ToContact2) in the helper class. Listing 2 contains the definition of the extension method (and its class).

Listing 2: An extension method that will work with the anonymous projection too.

public static class Helper
  {
    public static string ToContact2<T>(this T table,
      string title, string name)
    {
      const string mask = "{0}, {1}";
      return string.Format(mask, name, title);
    }
  }

Really getting as many aspects of the .NET Framework is critical to becoming inventing with how you use the framework. Although all of the examples are short, the CodeDOM, generics, generic delegates, Lambda expressions (c=>Console.WriteLine...) and extension methods were all employed in crafting the solutions.

If you this post helped you add a comment. If you want more juicy tidbits like this one then check my blog or check out my book LINQ Unleashed for C# from Sams.

Published Feb 26 2009, 06:59 PM by Paul Kimmel (Developer Express)
Technorati tags: LINQ, anonymous delegates, Generics

Comments

 

MESUT KOSUCU said:

nice post

thanks a lot

February 26, 2009 7:09 PM
 

richard morris said:

Not sure I can see a good reason to inject an anonymous delegate into an anonymous type as it's not going to have intimate knowledge of the structure to be able to do anything useful.  Other than of course because it can be done, which I agree is neat.

Projecting into a named class, with methods, would appear to be more useful, thoiugh a little more work.

February 27, 2009 7:17 AM
 

Paul Kimmel (Developer Express) said:

Richard's comment is reasonable. You might need a method just when you need it. One of the things I like to do is bend the language a little bit in order to explore possibilities and invent new things. Some inventions--like a gyroscopic and accelerometer-based pointing device--might be impractical. One could also think of this sort of code as code-calisthenics.

February 27, 2009 8:34 AM
 

Garth Henderson said:

Many thanks, Paul.  

Please continue to share observations even if they may not have a direct immediate implementation.

It is my hope that some day soon we well have a DX based forum that will allow us to collaborate significantly better.

Ideas should be connected through multiple relationships to other ideas.

DX supports a very rich variety of software projects.  My use of a particular component or aspect of a framework certainly shouldn't constrain how other coders choose to utilize the components.  

It will be great when we have a collaborative environment to clearly associate the usages of MS and DX technology.  It is a fact that many of us are integrating several competing components and frameworks to meet our needs.  Having a collaborative environment to support these common implementations would be helpful.  

It is not necessary to disagree on different ideas when all of the ideas achieve valuable professional (profitable) results.  Requests for additional information and deeper thinking should always be welcomed.

March 2, 2009 2:25 PM
 

CESAR F. QüEB said:

Thank you a lot for this sample... i found it very useful. Using the intrinsic DataContext entities is not possible return a List<Of T> collections with the orders for an specify customer due to the circular references  issues in the serialization process (is possible implementing one extension to the specific property, in partial class). This method gives me an idea to get the collection.

Regards

March 28, 2009 12:21 AM

Leave a Comment

(required)  
(optional)
(required)  
Verification code: Required
   
Add
Copyright © 1998-2010 Developer Express Inc.
ALL RIGHTS RESERVED