Mixing Extension Methods and Anonymous Types

In my recent post Overcoming the Limitations of Anonymous Types,
I talked about ways to get around the method scope and read-only
limitations of anonymous types.  These were fairly simple examples that
used reflection to gather data from the type once it had been passed
outside of the containing method.  You could see the properties of the
type and get the values, but it was not very easy to implement if you
really wanted to use this for something substantial.  Again, I do not
recommend this approach.  It is a better practice to use named classes
to pass data between methods in these types of situations, not to
mention that there are performance concerns when using reflection in
places that you shouldn't.  These examples are meant to show the power
of reflection and to explore some of the new features of the next
version of C#.

This time around I am using the new extension methods feature to
provide a method to get the value of any property that an anonymous
type exposes.  Since we don't know the actual type name for a given
anonymous type, we will create a method that extends the object type. 

 public static class ExtensionMethods
{
  // This is an extension method that will apply to all objects
  public static T ReflectPropertyValue<T>(this object obj, string propertyName)
  {
    // Check for empty or null propertyName arg
    if (String.IsNullOrEmpty(propertyName))
    {
      throw new ArgumentException
        ("'propertyName' cannot be null or empty.", "propertyName");
    }
    // Check for null obj arg
    if (obj == null)
    {
      throw new ArgumentNullException
        ("'obj' cannot be null.", "obj");
    }
    // Get the type of the object
    Type t = obj.GetType();
    // Get the property info for the specified property name
    PropertyInfo pi = t.GetProperty(propertyName);
    // If the returned PropertyInfo object is null, then it could not be found
    if (pi == null)
    {
      throw new Exception
        ("The 'propertyName' specified does not exist within this object.");
    }

    // Check to make sure that the expected type and the actual type match so
    // that we don't get an invalid cast
    if (typeof(T) != pi.PropertyType)
    {
      throw new Exception
        ("The expected type does not match the actual type");
    }

    // Return the value as the type expected
    return (T)pi.GetValue(obj, null);
  }
}

This just uses reflection (as in my previous post) to get the property value for a type.

Since this extension method is applied to all objects, we can use
this method on anonymous types as well. The code below shows how to use
this to get a typed value for a specified property name.

 private void ContainingMethod()
{
  // Create an anonymous type
  var anondata = new
  {
    IntegerVal = 1,
    DoubleVal = 2.0D,
    DateTimeVal = DateTime.Now,
    StringVal = "some string"       
  };

  // Pass the type to a method
  ExternalMethod(anondata);
}

private void ExternalMethod(object data)
{
  string i = data.ReflectPropertyValue<string>("StringVal");
  Console.WriteLine(i);
}

This code would output:

some string

This makes retrieving values from anonymous types much easier from
outside the bounds of the containing method. In a line of code, you
have a typed representation of the property value. You could also write
an extension method to allow you to set the value of a property if you
really wanted to.