Passing custom and anonymous types across code boundaries

Linq is great for grabbing entity objects. The code is simple, and you end up with known objects that you can use.

But, when you want to deal with anything slightly off the beaten track, it gets a bit harder. For example, if you have a Linq query that returns an anonymous type, you can easily manipulate it in the same code block. For example, to take a gratuitously silly example, if you had a Bird class…

public class Bird {
  private int m_Weight;
  public Bird(int Weight) {
    m_Weight = Weight;
  }
  public int Weight {
    get {
      return m_Weight;
    }
    set {
      m_Weight = value;
    }
  }
}

…then you could write a Linq query like this…

var someBirds = from b in birds where b.Weight > 2 select b;
foreach (Bird b in someBirds) {
  Console.WriteLine("  I weigh " + b.Weight.ToString() + "Kg");
}

…and since you are dealing with objects of type Bird, the compiler can cope happily.

Even if you are dealing with anonymous types, you’re OK in the same code block. Imagine the Bird class had a Name property (amongst others), then you could write code like this…

var someBirds = from b in birds where b.Weight
  select new { Name = b.Name, Weight = b.Weight };
foreach (var b in someBirds) {
  Console.WriteLine("My name is " + b.Name + ", and I weigh "
                   + b.Weight.ToString() + "Kg");
}

Now here, the variable b in the foreach loop is of an anonymous type, but as you’re in the same code block, the compiler knows what it’s dealing with.

The problem comes when you want to pass the Linq query to another code block. This can be as a parameter in a method, or as the result of a service call. Now you have a problem, as the code on the other side of the block boundary doesn’t know what the type of the query object is. The framework seems to fall apart at this point!

The simplest way (that I’ve found so far) is to create a utility class that you can use in the Linq query…

public class TmpBird {
  public int Weight { get; set; }
  public string Name { get; set; }
}

I called this TmpBird to distinguish it from the normal Bird class. Note that this class only needs the two properties that this query uses, and we are taking advantage of C#’s auto-implemented properties, which means we only need to supply the access modifier, type and name for property. C# creates a private member variable, and codes up the getter and setter methods.

Now we can change our Linq query to look like this…

var someBirds = from b in birds where b.Weight
  select new TmpBird { Name = "Ferret", Weight = b.Weight };

And everything works fine. As long as the code block that receives the query knows about the utility class, it can handle the query easily. In particular, code that crosses a boundary can handle the query sent back.

This has the advantage that you don’t have to send back a full entity object if you don’t want. In the above example, we only wanted the weight and name of the bird, so we could ignore any other properties. In this simple case, there wouldn’t have been any great loss in sending back the whole Bird object, but if you were dealing with bigger objects, it could make a significant difference.

For example, if you have a User object in your entity model, you may have a large number of properties. If you wanted to populate a drop-down list with users, so one could be chosen, you would only want the user ID and name. Instead of throwing around a collection of full User objects, you could create a light User utility class, and pass that around instead.

The one disadvantage of this approach is that you can end up with a proliferation of utility classes. However, if you make each class private to the code block that uses it, then the issue can be contained. If the query changes, then the code that uses it would need to know anyway, so updating the utility class isn’t such a huge issue.

Be First to Comment

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.