I have used extension methods to extend html helpers to make an RSS repeater:
public static string RSSRepeater(this HtmlHelper html, IEnumerable<IRSSable> rss)
{
string result="";
foreach (IRSSable item in rss)
{
result += "<item>" + item.GetRSSItem().InnerXml + "</item>";
}
return result;
}
So I make one of my business objects implement IRSSable, and try to pass this to the HTML helper. But I just cannot seem to make it work, I have tried:
<%=Html.RSSRepeater(ViewData.Model.GetIssues(null, null, "") as IEnumerable<IRSSable>) %>
Compiles fine, but null is passed
<%=Html.RSSRepeater(ViewData.Model.GetIssues(null, null, "")) %>
Intellisense moans about not being able to pass IEnumerable issue to IEnumberable IRSSable
- So how do you do it? That method I am calling definitly returns
IEnumberable<Issue>
and Issue definitly implements IRSSAble
Try this:
Ahh... try:
This then should allow you to pass any sequence of things that implement
IRSSable
- and the generic type inference should mean you don't need to specify theT
(asIssue
) yourself - the compiler will handle it.By the way - avoid concatenation here;
StringBuilder
is preferable:You're running into generic variance issues. Just because something implements
IEnumerable<Issue>
doesn't mean it implementsIEnumerable<IRssable>
. (It will in C# 4, but I'm assuming you're not using that :)You could make your extension method take just
IEnumerable
and callIEnumerable.Cast<IRssable>
on it though - that's probably the simplest approach.EDIT: Marc's suggestion is probably the better one, but I'll leave this answer here as it explains what's going on rather than just the fix :)