2008-11-28 3 views
4

я использовал методы расширения для расширения 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>) %> 

компилирует хорошо, но нуль передается

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

Intellisense стонет о не в состоянии передать IEnumerable вопрос на IEnumberable IRSSable

  • Итак, как вы это делаете? Этот метод я звоню возвращает IEnumberable<Issue> определенно и выпуск реализует IRSSAble определенно
+0

Не видя, что метод GetIssues делает это очень трудно сказать с уверенностью. – samjudson 2008-11-28 11:41:08

ответ

14

Ahh ... попробовать:

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

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

Кстати - avoid concatenation here; StringBuilder предпочтительнее:

StringBuilder result = new StringBuilder(); 

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

    return result.ToString(); 
+0

Ницца - нравится. Доверяйте вам сделать шаг назад и приблизиться к нему с лучшего направления :) – 2008-11-28 11:44:22

4

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

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

EDIT: Marc's suggestion, вероятно, лучше один, но я оставлю этот ответ здесь, как это объясняет, что происходит, а не просто исправить :)

+0

Да, спасибо за объяснение. – qui 2008-11-28 11:59:57

0

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

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