C# - Cannot implicitly convert type List to List

前端 未结 6 1501
生来不讨喜
生来不讨喜 2020-11-27 11:46

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

相关标签:
6条回答
  • 2020-11-27 12:22

    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).

    0 讨论(0)
  • 2020-11-27 12:25

    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());
    }
    
    0 讨论(0)
  • 2020-11-27 12:33

    Try this instead:

    List<contracts.IProduct> myList = new List<contracts.IProduct>((new List<dto.Product>()).Cast<contracts.IProduct>());
    
    0 讨论(0)
  • 2020-11-27 12:37

    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".

    0 讨论(0)
  • 2020-11-27 12:37

    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.  ");
            }
        }
    
    0 讨论(0)
  • 2020-11-27 12:39

    Just as a remark: Covariance and Contravariance in Generics was added in C# 4.0.

    0 讨论(0)
提交回复
热议问题