Stuart Thompson’s Tech Blog

Web 2.0 & Quality Development

Archive for the ‘C#’ Category

Null-Coalescing Operator

Posted by stuartthompson on August 10, 2007

While at a rather disappointing MSDN event yesterday, I came across one gem of C# 3.0 candy in the form of a null-coalescing operator.  This is basically a short-cut for the oft seen:

string emailAddress = parsedValue != null ? parsedValue : “(Not provided)”;

OR

string emailAddress = String.Empty;
if (parsedValue != null) {
emailAddress = parsedValue;
}
else {
emailAddress = “(Not provided)”;
}

Using the Null-Coalescing Operator
These can now instead be re-written using the new null-coalescing operator as:

string emailAddress = parsedValue ?? “(Not provided)”;

This can roughly be read as “Set emailAddress equal to parsedValue unless it is null, in which case set it to the literal (Not Provided)”.

Applications with Nullable Types
This is also very useful with the new nullable types.  For example, when converting an integer to its value type:

int? recordsAffected = null;
… code that might cause recordsAffected to contain a value …
int totalRecordsAffected += recordsAffected ?? 0;

Here a nullable int type can be added to a regular int without fear of an exception by subsituting 0 in the place of a null value.  It’s always nice to find new candy!

Posted in C# | Tagged: , | Leave a Comment »

Using Anonymous Method Predicates to Search Lists

Posted by stuartthompson on August 7, 2007

I use System.Collections.Generic.List all over the place.  Generics are a couple of years out of date and most people are done with them in terms of cool factor, but that doesn’t in any way detract from the coolness they add to my life each and every day.  I still eat toast and that’s been around for ages.  I answered a question this morning that made me realize that while the generic list class has been generally embraced by most, it perhaps has also been generally muddled by some attempting to keep up with the oft quick pace that is .NET.  I’ve seen quite a few development shops that stuck around on .NET 1.1 for a long time because of migration concerns and then very quickly “updated their code” to embrace .NET 2.0 without really giving people the time to absorb all of the new information.  One of these areas is with collection classes.

When a development shop moves to .NET 2.0, one of the first things you’ll see is a bunch of {blah}Collection class objects being removed from the codebase and their usage replaced with List throughout.  This is all well and good.  A smaller code surface area is easier to test and maintain, and most people didn’t ever fully finish building a complete collection class anyway, feeling that the code around finding, searching, comparing, etc… within the collection classes was always a little muddy.  It’s true that building a robust collection class is difficult, especially when considering an object model that involves some serious aggregation.

However, we seem to have found a new source for confusion on how to search collections in the adoption of the System.Collections.Generic.List class.  The question I answered this morning about searching a generic list is not the first I have received, so I thought I’d take the time to share a couple of techniques that I use and get feedback from others on their strategies.  What prompted me to write this article was a small snippet of code I received that looked like this:  (original code modified to protect the innocent)

string targetName = “Thompson”;

List myObjectList = new List();
… list is populated with some items …

MyObj selectedObject = null;
foreach (MyObj obj in myObjectList)
{
if (obj.Name == targetName)
{
selectedObject = obj;
}
}

The code looks reasonable from a first glance.  The original code was actually copied from within a collection class’ SearchByName() method when the class was being replaced with a System.Collections.Generic.List.  This is scary for a couple of reasons.  First of all, original code contains a couple of bugs that weren’t addressed as part of the migration probably because very little time was given to “move to .NET 2.0″. &nbp;Secondly, this probably isn’t an isolated case.  I suspect that this kind of refactoring is happening in a lot of other projects.  Let’s look at the code in a little more detail and think about some of the opportunities for improvement.

The first obvious bug is that if two objects exist in the list with the target name, the last one searched that matches is being set as the selected object.  This shouldn’t simply be handled by adding a “return” within the loop to return the first either (which I’ve seen in “fixes” before).  In this case it is probably important to know that more than one object matched the target name.  While seemingly minor, there is no lock statement around the foreach search, meaning that the list could be modified during the search by code in any thread with a reference to the list.  Wouldn’t it be nice if there were a way to find an item in a list without having to worry about such things?

The System.Collections.Generic.List class provides Find() and FindAll() methods that take a System.Predicate as a parameter.  Most developers I’ve watched tend to browse this method in Intellisense, think “Oh my god, I have no idea what this Predicate class is” and then code a method similar to the one listed above.  However, the System.Predicate generic really isn’t all that scary and is actually a really elegant solution to the problem.  Look at the following code for a second:

string targetName = “Thompson”;

List myObjectList = new List();
… list is populated with some items …

List matches = myObjectList.FindAll(delegate(MyObj compare)
{
return compare.Name == targetName;
});

Here, an anonymous method was used as an implementation of System.Predicate to determine whether the comparison of an object’s name to the target name was true.  That’s essentially how predicates work, they assert whether a particular predicate is true or not.  In this case, we are using them to determine whether or not a particular item in a collection matches certain search criteria.  The way that the FindAll() method works is to pass each object in the collection to the specified predicate and add the object to a match list if the predicate is true.  In the one call to FindAll() our code was able to determine all items in the list that have the specified target name.  Also, the Find() and FindAll() method correctly issue a lock statement upon the list to protect the search, as well as other finery around error handling for null objects in the list.  All of this code for free in a single method call.

Anonymous delegates do not have to be used for predicates, although they present the most graceful solution for a parameterized search.  What I mean by this is that if your search does not rely upon a parameter like targetName in the example above, you could pass a delagate implementation to the find method.  The example below shows how a predicate can be used to find items in the list with a name longer than 5 characters:

List myObjectList = new List();
… list is populated with some items …

List matches = myObjectList.FindAll(ObjNameLongEnough);

The method ObjNameLongEnough is defined as follows:

private bool ObjNameLongEnough(MyObj compare)
{
return compare.Name.Length > 5;
}

This example gives a better idea of how the anonymous method delegate is working by showing the signature of the System.Predicate that is expected.  Notice that the method signature of ObjNameLongEnough() takes a MyObj parameter.  The FindAll() method simply calls this delegate for each item in the list and adds the object to the match collection if the predicate returns true.  If the desired behavior was to find only the first match in the list, use the Find() method instead.

Astute readers are probably wondering if there is an overloaded version of System.Predicate that takes an additional search parameter.  This would have allowed for the first example that compared to target name to be coded as an actual delegate as opposed to an anonymous method by passing the targetName variable into the search delegate.  However, unfortunately, there is not an overloaded version.  This appears to stem from the computer science root that a predicate is simply a test that something is true of something.  Therefore a predicate cannot be parameterized as it would be testing its trueness(TM) to something in relation to something else.

IMHO anonymous methods are still a great solution to the problem and provide compact, readable code for searching generic list collections without having to worry about the finer points of locking, object null testing, and first match versus all matches.  Enjoy!

Posted in C# | Tagged: , , | Leave a Comment »

Overloaded Indexers cause Ambiguous Match

Posted by stuartthompson on April 13, 2007

Developing custom web server controls can be a powerful way to provide opportunity for code re-use while retaining strong design-time support and Visual Studio integration.  This is especially useful when developing a solution that will be handed off to a maintenance team as it allows full control of the rendering and behavior of your control whilst retaining ease of use and configuration for the maintenance team at a later date.  One of the common patterns that appears in such server controls is the definition of a child collection of items.  This is akin to the collection property Columns on the System.Web.UI.WebControls.DataGrid control.  When defined in .aspx, it looks like the following:

<asp:DataGrid id=”myGrid” runat=”server”>
<Columns>
… column definitions …
</Columns>
</asp:DataGrid>

This collection is used in the definition of the data-grid to define information about the columns that the control should create when it is rendered.  Similarly, a custom control might have a collection of child items that represent domain objects within your custom solution.

I came across an error in one custom server control I developed that manifested itself as an System.Web.HttpParseException with the error message ‘Parser error: Ambiguous match found’.  The collection property, shown as <ChildItems> in the code below, was highlighted as the source of the error:

<ctl:CustomControl id=”myControl” runat=”server”>
<ChildItems>
… child item definitions …
</ChildItems>
</ctl:CustomControl>

After a little bit of research, I found a Microsoft KnowledgeBase article (#823194) that seemed to describe the symptoms I was observing.  The article indicated that the problem was in the definition of the custom collection itself.  If the collection contained an overloaded indexer then the ASP.NET framework would raise the HttpParseException and display the observed “Parser error: Ambiguous match exception” message when trying to instantiate the control in the page hierarchy.

I quickly popped open the code for the collection class and saw that I had indeed added an overloaded indexer as part of a recent update to the control.  I had added the ability to retrieve an item from the collection by item name as it was useful by another control that aggregated the one exhibiting the error.  There was already an indexer defined for the collection that used an integer to retrieve an item from a specified position.  In terms of C# syntax and for other consumers of the class, having an overloaded indexer is perfectly legitimate, however testing revealed that it was indeed the new this[string] indexer that was causing the problem when ASP.NET tried to instantiate the control programatically and deserialize the .aspx definition into that object instance.  After commenting out the indexer and re-running my tests, the problem was gone.  I have since replaced the overloaded indexer with an additional GetBy…() method and updated the documentation accordingly.  This wasn’t a particularly tricky bug to track down, but it’s interesting nonetheless.

Posted in ASP.NET, C# | Tagged: , , , , | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.