Передача интерфейса в качестве параметра в метод расширения - PullRequest
4 голосов
/ 28 ноября 2008

Я использовал методы расширения для расширения помощников HTML, чтобы сделать репитер RSS:

    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;
    }

Итак, я заставляю один из моих бизнес-объектов реализовать IRSSable и пытаюсь передать его помощнику HTML. Но я просто не могу заставить его работать, я попробовал:

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

Компилируется нормально, но NULL пропущено

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

Intellisense стонет о невозможности передать IEnumerable проблему в IEnumberable IRSSable

  • Так как ты это делаешь? Тот метод, который я вызываю, определенно возвращает IEnumberable<Issue>, а Issue определенно реализует IRSSAble

Ответы [ 3 ]

14 голосов
/ 28 ноября 2008

Ааа ... попробуй:

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

Это тогда должно позволить вам передать любую последовательность вещей, которые реализуют IRSSable - и вывод общего типа должен означать, что вам не нужно указывать T (как Issue) самостоятельно - компилятор будет обрабатывать это.

Кстати - избегайте здесь конкатенации ; StringBuilder является предпочтительным:

    StringBuilder result = new StringBuilder();

    foreach (IRSSable item in rss)
    {
        result.Append("<item>").Append(item.GetRSSItem().InnerXml).Append("</item>");
    }

    return result.ToString();
4 голосов
/ 28 ноября 2008

Вы столкнулись с общими проблемами дисперсии . То, что что-то реализует IEnumerable<Issue>, не означает, что оно реализует IEnumerable<IRssable>. (Это будет в C # 4, но я предполагаю, что вы не используете это:)

Вы могли бы сделать так, чтобы ваш метод расширения взял IEnumerable и вызвал IEnumerable.Cast<IRssable> для него - это, вероятно, самый простой подход.

РЕДАКТИРОВАТЬ: Предложение Марка , вероятно, лучше, но я оставлю этот ответ здесь, поскольку он объясняет, что происходит, а не просто исправление:)

0 голосов
/ 28 ноября 2008

Попробуйте это:

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