Linq To Objects: Anonymous Types and Methods

One of the core language features that C# relies on heavily when working with Linq is implicit typing. Implicit typing allows users to create anonymous types, which are simply types constructed at compile time based on the RHS expression specified by using the new keyword in conjunction with the object initializer syntax.

Implicit typing also works with predefined types, however it’s important to note the difference between the two syntactically similar statements, as they yield very different results:

var a = new int [] { 42 };

Create a new instance of a predefined type – an array containing a single element with the integer value ’42’.

var b = new { a =  42 };

Creates a new compiler generated type – consisting of a single field, decorated with the value ‘a’, of the integer type. This instance contains the value ’42’ in its ‘a’ field.

The rest of the post will focus solely on the former construct.

Anonymous Types

Foundations

An example anonymous type can be created with the following expression,

var anon = new { Name = "Poe", Age = 19, Location = "Burrell, PA" };

The previous snippet will instruct the compiler to emit an immutable class with 3 fields, two strings and an integer. The IL that is actually generated looks something like this:

ldstr       "Poe"
ldc.i4.s    13
ldstr       "Burrell, PA"
newobj      <>f__AnonymousType<System.String,System.Int32,System.String>;..ctor

The important things to note in the previous snippet are the automatic type name generated by the compiler and that object initialization happens via the constructor.

The new type name generated by the compiler, “f__AnonymousType0”, is now bound to a generic type composed of an object with three fields of the type “System.String”, “System.Int32” and “System.String”, with the decorators (field names) “Name”, “Age” and “Location” respectively, in that exact order. Any future anonymous types constructed with that exact same types and decorators are said to be equal, so the compiler can reuse an existing anonymous type declaration in some circumstances to reduce overhead.

The reason an anonymous types fields are instantiated via the constructor is due to the fact that anonymous types are immutable.

Anonymous Type vs The Tuple Type

There is a some-what common misconception that since an anonymous type is an immutable generic type, the “var” keyword is just some syntactic sugar around creating another C# 3.0 type, the Tuple. However, this is not the case.

Tuples and anonymous types have different base types for one, tuple is a struct and an anonymous type is a class therefor they are have unique sets of rules at the CLR level. There is also the matter of the field decorators which make the anonymous type more developer friendly, however it limits the scope of the object to the block in which it was declared.

Outside of the scope in which an anonymous type is declared it must be referred to simply as an “Object”, or “Dynamic” if you want to remove compile time type checking on accessors, so you lose the ability to get its field values safely (Dynamic typing or Reflection are still possible, however I would conciser this horrible practice).

While on the other hand a Tuple always has the same static field decorators (Item1, Item2, etc.) so you can instantiate a Tuple inside a block, return it outside the scope of that block and still have a compile-time safe way of accessing its values.

Projections

Anytime the CLR emits an anonymous type it can be referred to as simply a “Projection”. However, there is a concise subset of anonymous type declarations that I’m referring to when I use the term “Projection” – explicitly property projection or object transformation.

For example, we could use the example anonymous type at the beginning of this post to illustrate how property projection works.

An important note about the following example is that anonymous types have a built-in overloaded “ToString()” implementation that emits a nicely formatted string representation of the instance, instead of the default implementation (from System.Object) which simply returns the fully qualified name of the type of the object.

var anon = new { Name = "Poe", Age = 19, Location = "Burrell, PA" };
var projection = new { Info = anon.ToString() };

When this code executes a new anonymous type will be created that has a single decorated field, ‘Info’, of the string type. This field will contain the value ‘{ Name = Poe, Age = 19, Location = Burrell, PA }’.

This may seem a bit trivial at first glance because this example is not very useful. We’re simply transforming an object with 3 distinct fields into a new object with a single field containing the concatenated value of the first objects field values. The need for this in real world situations is questionable at best.

However, a slightly more complicated example can demonstrate the power of projects in real word situations.

For example, let’s say we want to take a collection of “CanidateSkill” objects and join it against a collection of “JobDesiredSkill” objects, both of which are complex types. Normally, comparing complex types would require a custom comparison object. However, with Linq we can simply project out the primitive property we’re interested in and take advantage of built-in primitive comparison operations.

class CanidateSkill
{
    public Guid CanidateId { get; set; }
    public Guid SkillId { get; set; }
}

class JobDesiredSkill
{
    public Guid JobId { get; set; }
    public Guid SkillId { get; set; }
}

void Main()
{
    // Generate test data.
    List<Guid> skills =
        new List<Guid>( Enumerable.Range( 0, 20 ).Select( n => Guid.NewGuid() ) );

    List<CanidateSkill> canidateSkills = new List<CanidateSkill>
    (
        Enumerable.Range( 0, 10 ).Select( c => new CanidateSkill() { CanidateId = Guid.NewGuid(), SkillId = skills.ElementAt( c ) } )
    );

    List<JobDesiredSkill> desiredSkills = new List<JobDesiredSkill>
    (
        Enumerable.Range( 5, 15 ).Select( d => new JobDesiredSkill() { JobId = Guid.NewGuid(), SkillId = skills.ElementAt( d ) } )
    );

    // Use projects to extract the single field we're interested in and take advantage of built in primitive type comparisons.

    var anyDesiredSkills =
        canidateSkills.Any( c => desiredSkills.Select( ds => ds.SkillId ).Contains( c.SkillId ) ); // true

    var allDesiredSkills =
        canidateSkills.All( c => desiredSkills.Select( ds => ds.SkillId ).Contains( c.SkillId ) ); // false
}

Note that in the “Select” we don’t use the anonymous type syntax because we’re simply projecting a primitive, however we could do:

var anyDesiredSkills =
    canidateSkills.Any
    (
        c => desiredSkills.Select
        (
            ds =>
                new { Id = ds.SkillId }
        ).Contains
        (
            new { Id = c.SkillId }
        )
    );

And it would behave exactly the same way. You could also extend this to include multiple primitives that have built in equality compares, because by definition two anonymous instances are said to be equal if they have identical field declarations and values.

Anonymous Methods

An anonymous method is simply a method that is declared dynamically with the “delegate” keyword, or alternatively with the newer lambda syntax – ()=>, that behaves exactly like a “normal” method except that it doesn’t require a name, parameters or a return type. They’re essentially a way to pass a code block as a parameter.

The most common use for anonymous methods is probably creating event handlers.

Traditional delegate syntax:

Console.CancelKeyPress += delegate( Object o, ConsoleCancelEventArgs e )
    {
        Console.WriteLine( "Anonymous Cancel Event Raised" );
    };

Newer Lambda Syntax:

Console.CancelKeyPress += ( o, e ) =>
    Console.WriteLine( "Anonymous Cancel Event Raised" );
Recursion with Anonymous Methods

Anonymous methods are not named until after the delegate definition is declared. Hence, you can’t call an anonymous delegate from inside itself (recursion) by using it’s name.

There are however, a couple interesting ways around this limitation.

  • Use the StackFrame object to get the current method information from the stack and invoke it.
  • Use the MethodInfo objects “GetCurrentMethod” to invoke the currently executing method from inside itself.
For example, here is an anonymous recursive based version of Factoral:
Func<long, long> Factoral = delegate( long n )
{
    return n > 1 ?
        n *
        ( long )( MethodInfo.GetCurrentMethod().Invoke( null, new object[]{ n - 1 } ) )
        : n;
};

Alternatively, there is another clever workaround to this problem. It’s a bit more interesting.

Declare a variable with the same signature as the method you wish to call and set it to an arbitrary value. This will simply create the reference point for future invocations, and to satisfy the compiler restrictions for accessing uninitialized local variables. Then set the instance value of that variable to the anonymous method you wish to call, which will create a fixture to the method instance and will allow it to be invoked from within itself via the previously created reference point.

Take a look at the exact same method created using the previously described method.

Func<long, long> Factoral = default( Func<long, long> );

Factoral = f => f == 0 ? 1 : f * Factoral(f - 1);

Pretty neet, huh?

Anonymous Behaviors: Putting it all together

Now that I’ve shown how to create an anonymous types and methods, why don’t we see what happens when we put them together?

As I mentioned previously, anonymous types are compiler inferred types generated at compile-time based on the types of the fields declared inside the initializer syntax. So, what happens when the type of a field is an anonymous method? Some pretty cool stuff, that’s what.

For example if we combined everything we learned in this post, we might come up with something like this:

Func<long, long> Factoral = default( Func<long, long> );

var factorals = new []
{
    Enumerable.Range( 1, 10 ).Select
    ( 
        n => 
            new { Name = String.Concat( n, "!" ), Value = Factoral( n ) }
    )
};

Factoral = f => f == 0 ? 1 : f * Factoral(f - 1);

factorals.ToList().ForEach
(
    f =>
        Console.WriteLine( f )
);

Advertisements

2 comments on “Linq To Objects: Anonymous Types and Methods

  1. Pingback: User of anonymous delegate | C#Net

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s