Ich habe ein Projekt mit all meinen Schnittstellendefinitionen: RivWorks.Interfaces
Ich habe ein Projekt, in dem ich konkrete Implementierungen definiere: RivWorks.DTO
Ich habe das schon hunderte Male gemacht, aber aus irgendeinem Grund erhalte ich jetzt diesen Fehler:
Typ 'System.Collections.Generic.List <RivWorks.DTO.Product>' kann nicht implizit in 'System.Collections.Generic.List <RivWorks.Interfaces.DataContracts.IProduct>' konvertiert werden.
Schnittstellendefinition (verkürzt):
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; }
...
}
}
Konkrete Klassendefinition (verkürzt):
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
}
}
In einer anderen Klasse habe ich:
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>();
...
Irgendwelche Ideen, warum dies passieren könnte? (Und ich bin sicher, es ist etwas trivial Einfaches!)
quelle
Das kannst du nicht machen. Wenn Sie eine haben
List<IProduct>
, können Sie jedeIProduct
hineinstecken. Wenn Sie also einProduct2
Gerät haben, könnenIProduct
Sie es in die Liste aufnehmen. Die ursprüngliche Liste wurde jedoch als erstelltList<Product>
, sodass jeder, der die Liste verwendet, nur Objekte vom Typ erwartetProduct
, die nichtProduct2
in der Liste enthalten sind.In .NET 4.0, fügten sie Kovarianz und Kontra für Schnittstellen, so dass Sie konvertieren könnte
IEnumerable<Product>
zuIEnumerable<IProduct>
. Dies funktioniert jedoch immer noch nicht für Listen, da Sie über die Listenoberfläche sowohl "Sachen einfügen" als auch "Sachen rausholen" können.quelle
Nur als Bemerkung: Kovarianz und Kontravarianz in Generika wurden in C # 4.0 hinzugefügt.
quelle
Nun, Sie können dies verwenden!
Nun, um direkte Lösung zu geben,
quelle
Dies ist ein kleines Beispiel dafür.
quelle
Versuchen Sie stattdessen Folgendes:
quelle