我想知道为什么不能在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>
,问题出在哪里?如何解决问题?
答案 0 :(得分:2)
几乎不需要为用户代码中的集合实现IEnumerable<T>
。另请参见Why not inherit from List<T>?。这样做可能是您要解决的问题的错误方法。
现在您有一个变量Bookings model
,其中Bookings : IEnumerable<Booking>
,并且想为该变量分配一个IEnumerable<Booking>
-您不能。就像不能将Animal
实例分配给Dog
变量一样,狗是动物,但并非每只动物都是狗。
将model
的类型更改为IEnumerable<Booking>
,或者完全更改您的方法。
答案 1 :(得分:0)
即使Bookings != IEnumerable<Booking>
实现了Bookings
,也无法像这样IEnumerable<Booking>
进行广播。
您可以这样想,我的汽车有一个IDoors
界面,我的卡车有一个IDoors
界面。但是,称它们相同是没有意义的,它们只是共享相同的门合同。无论我是否尝试使用隐式强制转换,我都无法将卡车变成汽车,我所能做的就是说它们在车门上有相似之处
答案 2 :(得分:0)
问题出在变量model
private Bookings model;
尽管类模型实现了IEnumerable<Booking>
,但它不是repository.GetBookings()
返回的对象的同一类(是其父类)。
将此与以下内容进行比较:
class Person {...}
class Male : Person {...}
class Female : Person {...}
Person p = new Male();
Female f = p;
您不能仅将对象分配给不相关类的对象。
您需要编写一个转换器,将任何顺序的Bookings转换为Bookings类的对象。最简单的方法是添加一个构造函数:
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
。