为什么这样做:
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;
}
Run Code Online (Sandbox Code Playgroud)
但这确实不起作用(错误 - 无法将表达式转换为返回类型):
public IList<ICoupon> GetCouponsForSite(string siteSlug)
{
return _db.Coupons.Where(x => x.Site.slug == siteSlug)
.Select(x => new Coupon(x.id)).ToList();
}
Run Code Online (Sandbox Code Playgroud)
ito*_*son 10
因为db.Coupons ... ToList()返回的是IList<Coupon>
而不是IList<ICoupon>
. IList<Coupon>
不是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戳入其中,一切都很好,因为List已构建持有任何ICoupon,而不仅仅是实际的优惠券对象.)