Passing an interface as a parameter to an extension method

I used extension methods to extend html helpers to create 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 am making one of my business objects an IRSSable implementation and trying to pass it to an HTML helper. But I just can't get it to work, I tried:

 <%=Html.RSSRepeater(ViewData.Model.GetIssues(null, null, "") as IEnumerable<IRSSable>) %> 

Compiles but null is passed

 <%=Html.RSSRepeater(ViewData.Model.GetIssues(null, null, "")) %> 

Intellisense moans about impossibility to pass IEnumerable question IEnumberable IRSSable

  • So how do you do this? This method that I call definitely returns an IEnumberable<Issue> , and the problem definitely implements IRSSAble
+4
source share
3 answers

Ahh ... try:

  public static string RSSRepeater<T>(this HtmlHelper html, IEnumerable<T> rss) where T : IRSSable { ... } 

This should allow you to pass any sequence of things that implement IRSSable , and generic type output should mean that you do not need to specify T (as Issue ) yourself - the compiler will process it.

By the way, avoid concatenation here ; StringBuilder is preferred:

  StringBuilder result = new StringBuilder(); foreach (IRSSable item in rss) { result.Append("<item>").Append(item.GetRSSItem().InnerXml).Append("</item>"); } return result.ToString(); 
+14
source

You are using common issues with deviations . Just because something implements IEnumerable<Issue> does not mean that it implements IEnumerable<IRssable> . (This will be in C # 4, but I assume you are not using this :)

You can make your extension method only IEnumerable and call it IEnumerable.Cast<IRssable> , although this is perhaps the easiest approach.

EDIT: Marc suggestion is probably the best, but I will leave this answer here as it explains what is happening, not just the fix :)

+4
source

Try the following:

 <%=Html.RSSRepeater(ViewData.Model.GetIssues(null, null, "").Cast<IRSSable>()) %> 
0
source

All Articles