将接口作为参数传递给扩展方法
我已经使用扩展方法来扩展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()) %>