为什么这样做:
public IList<ICoupon> GetCouponsForSite(string siteSlug) { var coupons = _db.Coupons.Where(x => x.Site.slug == siteSlug) .Select(x => new Coupon(x.id)); var list = new List<ICoupon>(); foreach (var coupon in coupons) { list.Add(coupon); } return list; }
但这确实不起作用(错误 – 无法将表达式转换为返回类型):
public IList<ICoupon> GetCouponsForSite(string siteSlug) { return _db.Coupons.Where(x => x.Site.slug == siteSlug) .Select(x => new Coupon(x.id)).ToList(); }
解决方法
因为db.Coupons … ToList()返回IList<优惠券>而不是IList< ICoupon>.的IList<优惠券>不是来自IList< ICoupon>因为C#3不支持通用方差. (C#4确实支持通用方差,但在这种情况下它仍然不会得到.考虑到收到IList< ICoupon>的人可能会尝试将SomeEvilTypeThatImplementsICoupon填充到其中.但IList< Coupon>无法接受,因为SomeEvilTypeThatImplementsICoupon不是来自优惠券.有关此可兑换问题的讨论,请参阅
http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html,尽管情况略有不同,并且Eric Lippert文章从那里链接.)
(相比之下,你的第一个片段显式构造了一个List< ICoupon>,它可以包含任何实现ICoupon的东西,然后将一些Coupon对象放入该列表.现在如果接收者决定将SomeEvilTypeThatImplementsICoupon戳入其中,一切都很好,因为列表是为了保存任何ICoupon,而不仅仅是实际的优惠券对象.)