Почему я не могу сделать кастинг, если модель реализует интерфейс IEnumerable <Booking>? - PullRequest
0 голосов
/ 07 февраля 2019

Мне интересно, почему я не могу выполнить приведение в конструкторе моего ViewModel:

public BookingsViewModel()
{
    IEnumerable<Booking> bookingsDB = repository.GetBookings();
    model = bookingsDB; //exception
}

Это вызывает исключение:

Невозможно неявно преобразовать тип System.Collections.Generic.IEnumerable<Library2.Models.Booking>до Library2.Models.Bookings.Существует явное преобразование (вам не хватает приведения?)

Когда GetBookings() выглядит так:

public IEnumerable<Booking> GetBookings()
{
    var bookings = context.Bookings.
            Include(i => i.Book).
            Include(i => i.Reader).
            AsEnumerable().
            ToList();
    return bookings;
}

И Bookings модель выглядит так:

public class Bookings : IEnumerable<Booking>
{
    private List<Booking> bookingList = new List<Booking>();
    public void AddBooking(Booking booking)
    {
        bookingList.Add(booking);
    }
    public bool DeleteBooking(Booking booking)
    {
        return bookingList.Remove(booking);
    }
    public int BookingList
    {
        get
        {
            return bookingList.Count;
        }
    }
    public Booking this[int index]
    {
        get
        {
            return bookingList[index];
        }
    }
    public IEnumerator<Booking> GetEnumerator()
    {
        return bookingList.GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

В чем проблема, если Bookings реализует IEnumerable<Booking>?Как решить проблему?

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Вы не можете выполнить такой бросок, Bookings != IEnumerable<Booking>, хотя Bookings реализует IEnumerable<Booking>.

Вы можете думать об этом так, моя машина имеет интерфейс IDoors, мой грузовик имеетIDoors интерфейс.Однако не имеет смысла называть их одинаковыми, они просто разделяют один и тот же контракт на двери.Я не могу превратить свой грузовик в машину, независимо от того, как сильно я стараюсь с неявным составом актеров или нет, все, что я могу сделать, это сказать, что они имеют сходство в дверях

0 голосов
/ 07 февраля 2019

Проблема в переменной model

private Bookings model;

Хотя модель классов реализует IEnumerable<Booking>, она не является (родителем) того же класса объекта, возвращаемого repository.GetBookings().

Сравните это с:

class Person {...}
class Male : Person {...}
class Female : Person {...}

Person p = new Male();
Female f = p;

Вы не можете просто присвоить объект объекту несвязанного класса.

Вам нужно написать конвертер, который преобразует любую последовательностьБронирования в объект класса Бронирования.Самый простой способ - добавить конструктор:

public Bookings(IEnumerable<Booking> bookings)
{
    this.bookingList = bookings.ToList();
}

Примечание: bookingList - это новый список, содержащий те же элементы, что и бронирования.Если вы добавляете бронирование в исходный список, оно не добавляется к вашему объекту Bookings и наоборот.

Другие возможные улучшения: очевидно, вы планируете хранить свои заказы внутри списка.Почему бы не реализовать IList<Booking>.С очень небольшим усилием вы добавляете много функций

class Bookings : IList<Booking>, IReadonlyList<Booking>, IReadonlyCollection<Booking>
{
    public Bookings()
    {
        this.bookings = new List<Booking>();
    }

    public Bookings(IEnumerable<Booking> bookings)
    {
        this.bookings = bookings.ToList();
    }

    private readonly IList<Booking> bookings;

    public int Count => this.booking.Count;
    public void Add(Booking booking) {this.booking.Add(booking);}
    public void Remove(Booking booking) {this.booking.Remove(booking);}
    public IEnumerator<Booking> GetEnumerator() {return this.booking.GetEnumerator();}
    etc.
}

Примечание. Если в Visual Studio щелкнуть правой кнопкой мыши на IList<Bookin> и выбрать «Быстрые действия и рефакторинг», все функции будут реализованы одновременно.,Можно даже сказать, что все эти функции должны использовать this.booking.

0 голосов
/ 07 февраля 2019

Вряд ли когда-либо нужно реализовывать IEnumerable<T> для коллекций в пользовательском коде.Смотрите также Почему бы не наследовать от List ? .Это, вероятно, неправильный подход к проблеме, которую вы пытаетесь решить.

Теперь у вас есть переменная Bookings model, где Bookings : IEnumerable<Booking>, и вы хотите присвоить IEnumerable<Booking> этой переменной -ты не можешьТочно так же, как нельзя присвоить экземпляр Animal переменной Dog - собака - это животное, но не каждое животное - это собака.

Либо измените тип model на IEnumerable<Booking>, или измените свой подход вообще.

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