Интерфейсы C # и общие списки - PullRequest
3 голосов
/ 20 января 2010

У меня есть интерфейс, определенный как:

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; }
        ...
        [XmlElement]
        [DataMember(Name = "buttonPositionCSS", Order = 14)]
        string buttonPositionCSS { get; set; }
    }
}

У меня есть конкретная реализация, например:

namespace RivWorks.Model.Objects
{
    [DataContract(Name = "Product", Namespace = "http://rivworks.com/DataContracts/2009/01/15")]
    public class Product : IProduct
    {
        #region Declarations
        private Guid _productID;
        private long _altProductID;
        private Guid _companyId;
        ...
        private string _buttonPositionCSS;
        #endregion

        #region IProduct Members
        public Guid ProductID { get { return _productID; } set { _productID = value; } }
        public long alternateProductID { get { return _altProductID; } set { _altProductID = value; } }
        public Guid CompanyId { get { return _companyId; } set { _companyId = value; } }
        ...
        public string buttonPositionCSS { get { return _buttonPositionCSS; } set { _buttonPositionCSS = value; } }
        #endregion
    }
}

У меня есть другой интерфейс, определенный как:

namespace RivWorks.Interfaces.Services
{
    public interface IProductManager
    {
        #region Products
        IProduct GetProductById(Guid productId);
        List<IProduct> GetProductByCompany(Guid companyId);
        int SaveProduct(IProduct product);
        int DeleteProduct(Guid productId);
        #endregion
    }
}

У меня есть класс, определенный как:

namespace RivWorks.Controller
{
    public class ProductManager : IProductManager
    {
        #region Declare Models
        private static RivWorks.Model.Negotiation.RIV_Entities _dbRiv = RivWorks.Model.Stores.RivEntities(AppSettings.RivWorkEntities_connString);
        private static RivWorks.Model.NegotiationAutos.RivFeedsEntities _dbFeed = RivWorks.Model.Stores.FeedEntities(AppSettings.FeedAutosEntities_connString);
        #endregion

        #region Products
        public IProduct GetProductById(Guid productId)
        {
            // deleted for simplicity sake
            return product;
        }
        public List<IProduct> GetProductByCompany(Guid companyId)
        {
            var company = (from a in _dbRiv.Company where a.CompanyId == companyId select a).First();
            var companyDetails = from a in _dbRiv.AutoNegotiationDetails where a.CompanyId == companyId select a;
            // ################################################## //
            List<IProduct> productList = new List<RivWorks.Model.Objects.Product>();
            // ################################################## //
            // deleted for simplicity sake
            return productList;
        }
        public int SaveProduct(IProduct product)
        {
            return 0;  // stub
        }
        public int DeleteProduct(Guid productId)
        {
            return 0;  // stub
        }
        #endregion
    }
}

Я получаю эту ошибку во время компиляции:

Невозможно неявно преобразовать тип 'System.Collections.Generic.List ' в 'System.Collections.Generic.List '

Система очень ориентирована на службы (WCF, WebOrb и т. Д.), И я хотел представить интерфейсы в качестве моих контрактов. У меня есть Модель и Контроллер в .NET, и я использую Сервисы как Представления (прокси) для сторонних потребителей (реальное Представление).

Что я пропускаю или делаю неправильно?

Ответы [ 5 ]

5 голосов
/ 20 января 2010

Попробуйте изменить:

List<IProduct> productList = new List<RivWorks.Model.Objects.Product>();

Кому:

List<IProduct> productList = new List<IProduct>();

Или (если вам нужно работать с элементами Списка как с их конкретными реализациями, а не с Интерфейсом, прежде чем возвращать список):

List<RivWorks.Model.Objects.Product> productList = 
    new List<RivWorks.Model.Objects.Product>();

// Do some work here.

return productList.Cast<IProduct>().ToList();
4 голосов
/ 20 января 2010

Вы создаете список Product с, но он ожидает список IProduct с.В этом случае они не взаимозаменяемы (что, если кто-то попытается добавить IProduct в список, который не a Product?)

Изменить

List<IProduct> productList = new List<RivWorks.Model.Objects.Product>();

до

List<IProduct> productList = new List<IProduct>();
4 голосов
/ 20 января 2010

Вам необходимо изменить эту строку:

List<IProduct> productList = new List<RivWorks.Model.Objects.Product>(); 

на

List<IProduct> productList = new List<IProduct>(); 

Поскольку вы возвращаете список с интерфейсом в качестве универсального типа, создайте экземпляр списка с помощью универсальноговведите.

Вы сможете добавить классы, которые его реализуют.

1 голос
/ 20 января 2010

Обобщения в C # просто не работают таким образом.

Смотрите здесь

Если B является подклассом A, C не являетсяt подкласс C .

1 голос
/ 20 января 2010

Вы предполагаете, что класс «Общий список» понимает, что если вы объявляете «Список IP-продуктов», то он такой же, как «Список продуктов».Вам необходимо объявить список следующим образом:

List<IProduct> = new List<Iproduct>();

Затем вы можете добавить экземпляры Product.

Это можно сделать (при определенных обстоятельствах) только из .net Faramework версии 4когда со-и контравариантность для родовых типов вводятся в Framework.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...