views:

145

answers:

6

Hello,

I'm new to C# and am stuck on the following. I have a Silverlight web service that uses LINQ to query a ADO.NET entity object. e.g.:

[OperationContract]
public List<Customer> GetData()
{
    using (TestEntities ctx = new TestEntities())
    {
        var data = from rec in ctx.Customer
                   select rec;
        return data.ToList();
    }
}

This works fine, but what I want to do is to make this more abstract. The first step would be to return a List<EntityObject> but this gives a compiler error, e.g.:

[OperationContract]
public List<EntityObject> GetData()
{
    using (TestEntities ctx = new TestEntities())
    {
        var data = from rec in ctx.Customer
                   select rec;
        return data.ToList();
    }
}

The error is:

Error 1 Cannot implicitly convert type 'System.Collections.Generic.List<SilverlightTest.Web.Customer>' to 'System.Collections.Generic.IEnumerable<System.Data.Objects.DataClasses.EntityObject>'. An explicit conversion exists (are you missing a cast?)

What am i doing wrong?

Thanks,

AJ

+3  A: 

Even though Customer inherits from EntityObject, List<Customer> doesn't inherit from List<EntityObject>, because generic type covariance is not supported (in C# 4.0, covariance is supported for interfaces, but not for IList<T>).

If you could assign a List<Customer> to a variable of type List<EntityObject>, it would allow you to do something like that :

List<EntityObject> list = new List<Customer>();
list.Add(new Product()); // assuming Product inherits from EntityObject

This code is obviously broken : you can't add a Product to a List<Customer>. That's why it's not allowed

Thomas Levesque
A: 
[OperationContract]
public List<EntityObject> GetData()
{
    using (TestEntities ctx = new TestEntities())
    {
        var data = from rec in ctx.Customer
                   select (EntityObject)rec;
        return data.ToList();
    }
}

you can't cast List to List even if D derives from B. It is called covariance and works with arrays only. It will be fully introduced in C# 4.0

Andrey
A: 

Your var data contains Customer objects, your return is a list with EntityObjects.

You'll have to cast them:

data.ConvertAll(obj => (EntityObject) obj).ToList();
Carra
I like this, but it didn't work for me as data does not have a ConvertAll method.
AJ
A: 

You could do

data.Cast<EntityObject>().ToList();
juharr
A: 

Beyond the data.Cast<EntityObject>().ToList();, you will probably need to define the derived types on as know types, so WCF will know how to serialize the derived objects.

http://msdn.microsoft.com/en-us/library/ms730167.aspx

Justice
A: 

You might consider looking at this blog post: http://10rem.net/blog/2009/07/13/sharing-entities-between-wcf-and-silverlight

silverfighter