将接口作为参数传递给扩展方法

我已经使用扩展方法来扩展html助手来制作RSS转发器:

public static string RSSRepeater(this HtmlHelper html, IEnumerable rss) { string result=""; foreach (IRSSable item in rss) { result += "" + item.GetRSSItem().InnerXml + ""; } return result; } 

所以我让我的一个业务对象实现IRSSable,并尝试将其传递给HTML帮助器。 但我似乎无法使它工作,我尝试过:

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

编译正常,但传递null

  

Intellisense抱怨无法将IEnumerable问题传递给IEnumberable IRSSable

  • 你是怎么做到的? 我正在调用的那个方法IEnumberable返回IEnumberable并且问题肯定会实现IRSSAble

啊……试试:

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

然后,这应该允许您传递实现IRSSable任何序列 – 并且generics类型推断应该意味着您不需要自己指定T (作为Issue ) – 编译器将处理它。

顺便说一句 – 避免在这里连接 ; StringBuilder是首选:

  StringBuilder result = new StringBuilder(); foreach (IRSSable item in rss) { result.Append("").Append(item.GetRSSItem().InnerXml).Append(""); } return result.ToString(); 

您遇到了通用差异问题 。 仅仅因为某些实现IEnumerable并不意味着它实现了IEnumerable 。 (它将在C#4中,但我假设你没有使用它:)

您可以使您的扩展方法仅使用IEnumerable并在其上调用IEnumerable.Cast – 这可能是最简单的方法。

编辑: 马克的建议可能是更好的,但我会在这里留下这个答案,因为它解释了发生了什么而不仅仅是修复:)

试试这个:

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