Thursday, March 4, 2010

Generic Interface Interesting-ness

I wanted to set up a generic extension method that would bind a Repeater to the type T Items that I passed in. The definition was:

public static void bind_with<T>(this Repeater repeater,INavigation<T> navigation)
{
if(navigation.Items.Count() > 0)
{
repeater.DataSource = navigation.Items;
repeater.DataBind();

}

}


So obviously, T has to have the Items collection. My interface looked like this:

interface INavigation<T>
-- IEnumerable<T> Items

My Navigation classes (TopNavigation and SideNavigation) already had the Items collection, so I just tacked the interface on to the class declaration, and it passed the compilation test.

Now for the interesting part... when I cast the input to the correct type, I do not have to use the generic method signature as it is redundant. So I call the method like this:

bind_with((SideNavigationItem)e.Item.DataItem)

The method casts SideNavigationItem to INavigationItem<SideNavigationItem>, which has the collection of Items<SideNavigationItem>. No need to use the generic signature.

But even further still, I can also use this:

bind_with((SideNavigation)e.Item.DataItem)

which implements INavigation<SideNavigationItem>, and is also cast the same way. The type parameter defines the type of the Items collection, so it works both ways. I was also able to use:

bind_with(site.SideNavigation).

Cool!

I overloaded the method in order to use it with CmsPage.Articles collection, which is not INavigation at all. I guess I could use interface ICmsCollection, and then have only one method, but I don't know...

No comments:

Post a Comment