Generic list typecasting problem
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.:
开发者_如何学JAVA[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
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
[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
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();
You could do
data.Cast<EntityObject>().ToList();
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
精彩评论