Передача различного контента, который реализует тот же интерфейс - PullRequest
3 голосов
/ 02 сентября 2010

У меня есть несколько классов Linq2Sql, таких как "Article" "NewsItem" "Product".

У них всех есть заголовок, у всех есть уникальный идентификатор, и у них всех есть Сводка.

Итак, я создал интерфейс под названием IContent

public interface IContent {
    int Id { get; set; }
    String Title { get; set; }
    String Summary { get; set; }
    String HyperLink { get; set; }
}

В моем коде я пытаюсь сделать возможным передать List<T>, который реализует IContent, а затем использовать те общие свойства, которые я реализовал в каждом из частичных классов в моем проекте.

Итак, просто чтобы уточнить

Article является организацией Linq. Я создаю частичный класс и реализую IContent Вот фрагмент кода Article.cs:

   #region IContent Members

    public int Id {
        get {
            return this.ArticleID;
        }
        set {
            this.ArticleID = value;
        }
    }

Довольно просто. В моем коде я пытаюсь это сделать, но я не знаю, где я иду не так:

List<IContent> items;

MyDataContext cms = new MyDataContext();

items = cms.GetArticles();  
// ERROR: Can not implicitly convert List<Article> to List<IContent>

Если мой Article класс реализует IContent, почему я не могу перейти в Статьи? Я не знаю, какие объекты будут переданы.

Я знаю, что могу сделать это с наследованием базового класса, но использование LinqToSQL не использует обычные объекты.

Я уверен, что я упускаю что-то простое.

Ответы [ 3 ]

7 голосов
/ 02 сентября 2010

Это потому, что класс List и интерфейс не являются ковариантными.Если вы используете .NET 4.0 и C # 4.0, вы можете использовать ковариацию в интерфейсе IEnumerable<>, что должно быть хорошо для приложений LINQ.

Есть хороший FAQ по этим темам.

1 голос
/ 02 сентября 2010

Это классический случай, который требует ковариации в C # 4.0.Вам нужно только изменить List<Article> на IEnumerable<Article>, чтобы это назначение работало:

IEnumerable<IContent> articles = myContext.GetArticles();

Если вы застряли в .NET 3.5, вы можете просто использовать Linq Cast<T>():

IEnumerable<IContent> articles = myContext.GetArticles().Cast<IContent>();
1 голос
/ 02 сентября 2010

Вы пробовали

items = cms.GetArticles().Cast<IContent>().ToList();  
...