Solving the anonymous types problem with tuples

One of my first posts on this blog was about the problem of using anonymous types when you want to send the data outside of your current class. At the time, the only way I knew to solve this was to create a simple class that had the structure of the anonymous type, and create one of these instead of the anonymous type. I do this regularly, although I have taken to naming such classes CustomerOverview, OrderOverview, etc, instead of CustomerTmp as I did in that blog post, as they aren’t really temporary classes at all, they are slim, flattened overviews of the class.

This approach works well, but it can have its downsides. One, as mentioned in that post, is that it is easy to end up with a proliferation of classes, many of which may only be used in one location in the code. If the classes represent lightweight views of entities in the model (such as the two examples shown above), then I don’t worry about this, as it is clear what they represent, and it’s fairly certain that I’ll end up using them somewhere else at some point.

However, the problem does become more apparent when the classes are very specific to one part of the code. I feel uncomfortable having classes that don’t really represent anything in the object model as a whole. Granted, this isn’t a very common scenario, as if your code is structured sensibly, you will probably find that you don’t have these artificial classes, but it is something that happens every now and then.

For some odd reason, I was struck with an idea whilst I was washing my face the other morning! Now why this would pop into my head at 6am, when I hadn’t even thought about the issue for a year or so is beyond me, but I don’t claim to understand the workings of the human mind, especially one that is bleary from lack of sleep!

A lesser-known, but intriguing class

One of the less-known and more interesting (but ultimately useless in my experience) additions to the .NET framework version 4 was the Tuple class. This generic class allows you to create an object that consists of up to eight pieces of information of a specified type (Note: the slightly arbitrary reason why they picked eight as the maximum can be found in this MSDN Magazine article).

As an example, suppose you want to get a list of customer names and database IDs, but don’t need any of the other information in your customer entity. Instead of creating a CustomerOverview class, you could just create a Tuple<int, string> which would hold the two pieces of information. Thus, you may have a method with a signature like…

  public List<Tuple<int, string>> GetCustomerIdAndNames() {
    List<Tuple<int, string>> customers = new List<Tuple<int, string>>();
    // In reality, this would be populated from a database...
    customers.Add(new Tuple<int, string>(1, "Fred"));
    // etc...
    return customers;

So far so good. All of this looks jolly useful eh? So why did I describe it as ultimately useless? Only because my few experiences with using the Tuple class have ended up with changes in the requirements, which meant that every bit of code that used the Tuple had to be changed, at which point it became clear that it would have been much better design to have used a WhateverOverview class in the first place. So, whilst it’s an interesting addition to the framework, it’s one that I have never actually used (for very long anyway).

All that changed at 6am the other day. I had a flash of inspiration, which can be quite unnerving at that time of the morning!

Binding ASP.NET Repeaters to collections of Tuples

The issue I had that prompted that old blog post was sending data to an ASP.NET page, where it would be rendered using a Repeater control. For those of you not familiar with ASP.NET, this server-side control allows you to display a collection of items on a web page, without having to write all the code to loop through the collection and render it yourself. You just set up a simple template, bind the collection to the control, and the ASP.NET rendering engine does it for you. Now, those masochists who like writing everything themselves (such as those who use ASP.NET MVC!) might turn their noses up at such ideas, but as a professional ASP.NET developer for many years, I rely on controls like this to help me work more quickly. Microsoft provide a robust and efficient way of doing a job, why should I ignore it and do the whole thing by hand?

Anyway, the problem comes when you want to pass a collection of anonymous types to a Repeater. As the rendering engine needs to know the of each item in type of the collection, so that it can handle it appropriately, you can’t bind a collection of anonymous types to a Repeater. So, to continue my earlier example, if you want to use just the customer ID and name in the Repeater, you either have to send across the whole Customer entity (which may involve a large amount of unneeded data), or create a CustomerOverview class, and pass a collection of those.

In this case, a customer is a logical enough entity that you might want to create the CustomerOverview, but there are many cases where you wouldn’t. The specific collection of data items you want may be unique to this view, and creating a custom class for it would pollute the overall object model.

The simple answer to the problem is to generate a collection of Tuples, and pass that to the Repeater. As the Tuple is a known class, and the instance of it is strongly-typed, the ASP.NET engine won’t have any problem with it at all, and can happily render the data without the need for an overview class.

A fairly simple answer, using a class that turned out not to be so useless after all!

A caveat

I would be remiss if I didn’t end off with a comment about this approach. Although it works, and neatly solves the problem, I have to say that I’m still not a huge fan of using Tuples, especially when they are going to be passed outside of the class in which they are created. The reason is simply as I stated above, that requirements change, and if you find the need to change the length of the Tuple, or change the type of one of the items, you end up having to modify code in multiple classes. This gives the very strong feeling that you’re working with strongly-coupled code, which is never a good idea.

Having said that, many times when you pass a collection to a Repeater, you don’t actually need any code in the ASP.NET code-behind, as most of the data binding can be done automatically, so you probably don’t need any code in the code-behind that is specific to the Tuple in question. Therefore, if you change the Tuple where it is generated, you won’t need to change anything in the ASP.NET for it to continue working. This is especially true if you are using MVP, where the presenter can take care of any formatting that you want on the data items. In a case like this, I would be happy to use Tuples.

Phew, that was quite a lot of thought for first thing in the morning!

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.