views:

45

answers:

3

I have multiple Linq2Sql Classes such as "Article" "NewsItem" "Product".

They all have a title, they all have a unique ID and they all have a Summary.

So, I created an interface called IContent

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

In my code, I'm trying to make it possible to pass a List<T> that implements IContent and then use those common properties that I have implemented in each of the partial classes in my project.

So, just to clarify

Article is a Linq Entity. I create a partial class and implement IContent Here's a snippet of Article.cs:

   #region IContent Members

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

Pretty Simple. In my code I'm trying to this, but I don't know where I'm going wrong:

List<IContent> items;

MyDataContext cms = new MyDataContext();

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

If my Article class implement IContent why can't I pass in Articles? I don't know what the objects that are going to be passed in.

I know I can do this with Inheriting a base class, but using LinqToSQL doesn't use regular objects.

I'm sure it's something simple that I'm missing.

+7  A: 

This is because the List class and interface aren't covariant. If you're using .NET 4.0 and C# 4.0, you can actually use covariance on the IEnumerable<> interface, which should be okay for LINQ applications.

There's a good FAQ covering those topics.

Lucero
So... if i passed an `IEnumerable<Article>` to an `IEnumerable<IContent>` it would work? I'm using .Net 3.5 so I'm guessing I'm hooped. I'm wondering what a good solution is.
Atømix
Yes, that would work with 4.0. With 3.5, you can use the `Cast()` LINQ extension method.
Lucero
+1  A: 

Have you tried

items = cms.GetArticles().Cast<IContent>().ToList();  
code4life
I think you were the first to state the need to `Cast`
Atømix
+1  A: 

This is classic case that calls for co-variance in C# 4.0. You only have to change List<Article> to IEnumerable<Article> to make this assignemnt work:

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

If you are stuck with .NET 3.5 you can just use Linq Cast<T>():

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