code

형식 목록을 암시 적으로 변환 할 수 없습니다.

codestyles 2020. 10. 5. 07:59
반응형

형식 목록을 암시 적으로 변환 할 수 없습니다. 목록에


모든 인터페이스 정의
가있는 프로젝트가 있습니다 : RivWorks.Interfaces 구체적인 구현을 정의하는 프로젝트가 있습니다 : RivWorks.DTO

나는 전에 이것을 수백 번 수행했지만 어떤 이유로 지금이 오류가 발생합니다.

암시 적으로 'System.Collections.Generic.List <RivWorks.DTO.Product>'형식을 'System.Collections.Generic.List <RivWorks.Interfaces.DataContracts.IProduct>'로 변환 할 수 없습니다.

인터페이스 정의 (단축) :

namespace RivWorks.Interfaces.DataContracts
{
    public interface IProduct
    {
        [XmlElement]
        [DataMember(Name = "ID", Order = 0)]
        Guid ProductID { get; set; }
        [XmlElement]
        [DataMember(Name = "altID", Order = 1)]
        long alternateProductID { get; set; }
        [XmlElement]
        [DataMember(Name = "CompanyId", Order = 2)]
        Guid CompanyId { get; set; }
        ...
    }
}

구체적인 클래스 정의 (단축) :

namespace RivWorks.DTO
{
    [DataContract(Name = "Product", Namespace = "http://rivworks.com/DataContracts/2009/01/15")]
    public class Product : IProduct
    {
        #region Constructors
        public Product() { }
        public Product(Guid ProductID)
        {
            Initialize(ProductID);
        }
        public Product(string SKU, Guid CompanyID)
        {
            using (RivEntities _dbRiv = new RivWorksStore(stores.RivConnString).NegotiationEntities())
            {
                model.Product rivProduct = _dbRiv.Product.Where(a => a.SKU == SKU && a.Company.CompanyId == CompanyID).FirstOrDefault();
                if (rivProduct != null)
                    Initialize(rivProduct.ProductId);
            }
        }
        #endregion

        #region Private Methods
        private void Initialize(Guid ProductID)
        {
            using (RivEntities _dbRiv = new RivWorksStore(stores.RivConnString).NegotiationEntities())
            {
                var localProduct = _dbRiv.Product.Include("Company").Where(a => a.ProductId == ProductID).FirstOrDefault();
                if (localProduct != null)
                {
                    var companyDetails = _dbRiv.vwCompanyDetails.Where(a => a.CompanyId == localProduct.Company.CompanyId).FirstOrDefault();
                    if (companyDetails != null)
                    {
                        if (localProduct.alternateProductID != null && localProduct.alternateProductID > 0)
                        {
                            using (FeedsEntities _dbFeed = new FeedStoreReadOnly(stores.FeedConnString).ReadOnlyEntities())
                            {
                                var feedProduct = _dbFeed.AutoWithImage.Where(a => a.ClientID == companyDetails.ClientID && a.AutoID == localProduct.alternateProductID).FirstOrDefault();
                                if (companyDetails.useZeroGspPath.Value || feedProduct.GuaranteedSalePrice > 0)     // kab: 2010.04.07 - new rules...
                                    PopulateProduct(feedProduct, localProduct, companyDetails);
                            }
                        }
                        else
                        {
                            if (companyDetails.useZeroGspPath.Value || localProduct.LowestPrice > 0)                // kab: 2010.04.07 - new rules...
                                PopulateProduct(localProduct, companyDetails);
                        }
                    }
                }
            }
        }
        private void PopulateProduct(RivWorks.Model.Entities.Product product, RivWorks.Model.Entities.vwCompanyDetails RivCompany)
        {
            this.ProductID = product.ProductId;
            if (product.alternateProductID != null)
                this.alternateProductID = product.alternateProductID.Value;
            this.BackgroundColor = product.BackgroundColor;
            ...
        }
        private void PopulateProduct(RivWorks.Model.Entities.AutoWithImage feedProduct, RivWorks.Model.Entities.Product rivProduct, RivWorks.Model.Entities.vwCompanyDetails RivCompany)
        {
            this.alternateProductID = feedProduct.AutoID;
            this.BackgroundColor = Helpers.Product.GetCorrectValue(RivCompany.defaultBackgroundColor, rivProduct.BackgroundColor);
            ...
        }
        #endregion

        #region IProduct Members
        public Guid ProductID { get; set; }
        public long alternateProductID { get; set; }
        public Guid CompanyId { get; set; }
        ...
        #endregion
    }
}

다른 수업에는 다음이 있습니다.

using dto = RivWorks.DTO;
using contracts = RivWorks.Interfaces.DataContracts;
...
public static List<contracts.IProduct> Get(Guid companyID)
{
    List<contracts.IProduct> myList = new List<dto.Product>();
    ...

왜 이런 일이 일어날 지 아이디어가 있습니까? (그리고 나는 그것이 사소한 일이라고 확신합니다!)


네, C #의 공분산 제한입니다. 한 유형의 목록을 다른 목록으로 변환 할 수 없습니다.

대신에:

List<contracts.IProduct> myList = new List<dto.Product>();

당신은 이것을해야합니다

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


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


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


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());
}

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.  ");
        }
    }

Try this instead:

List<contracts.IProduct> myList = new List<contracts.IProduct>((new List<dto.Product>()).Cast<contracts.IProduct>());

참고URL : https://stackoverflow.com/questions/2640738/c-sharp-cannot-implicitly-convert-type-listproduct-to-listiproduct

반응형