I have a project with all my Interface definitions: RivWorks.Interfaces
I have a project where I define concrete implmentations: RivWorks.DTO
I\'ve done this hu
Yep it's a covariance limitation in C#. You can't convert a list of one type to a list of another.
Instead of:
List<contracts.IProduct> myList = new List<dto.Product>();
You have to do this
List<contracts.IProduct> myList = new List<contracts.IProduct>();
myList.Add(new dto.Product());
Eric Lippert explains why they implemented it this way: http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
(And why it is different than working with arrays of items).
Well, you can use this!
class A {}
class B : A {}
...
List<B> b = new List<B>();
...
List<A> a = new List<A>(b.ToArray());
Now, to give direct solution,
using dto = RivWorks.DTO;
using contracts = RivWorks.Interfaces.DataContracts;
...
public static List<contracts.IProduct> Get(Guid companyID) {
List<dto.Product> prodList = new List<dto.Product>();
...
return new List<contracts.IProduct>(prodList.ToArray());
}
Try this instead:
List<contracts.IProduct> myList = new List<contracts.IProduct>((new List<dto.Product>()).Cast<contracts.IProduct>());
You can't do that. If you have a List<IProduct>
, you can put any IProduct
in it. So if you have a Product2
which implements IProduct
you could put it in the list. But the original list was created as List<Product>
, so anyone using the list would expect only objects of type Product
, not Product2
to be in the list.
In .NET 4.0, they added covariance and contravariance for interfaces, so you could convert IEnumerable<Product>
to IEnumerable<IProduct>
. But this still doesn't work for lists, since the list interface allows you both to "put stuff in" and "get stuff out".
This is a little example how to do it.
public void CreateTallPeople()
{
var tallPeopleList = new List<IPerson>
{
new TallPerson {Height = 210, Name = "Stevo"},
new TallPerson {Height = 211, Name = "Johno"},
};
InteratePeople(tallPeopleList);
}
public void InteratePeople(List<IPerson> people)
{
foreach (var person in people)
{
Console.WriteLine($"{person.Name} is {person.Height}cm tall. ");
}
}
Just as a remark: Covariance and Contravariance in Generics was added in C# 4.0.