Overloaded Indexers cause Ambiguous Match

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.

This entry was posted in ASP.NET, C# and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *