为什么这样做:

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<Coupon>而不是IList<ICoupon>IList<Coupon>不是从IList<ICoupon>派生的,因为C#3不支持泛型方差。 (C#4确实支持泛型方差,但在这种情况下仍不会派生。考虑到谁收到IList<ICoupon>的人都可以尝试将SomeEvilTypeThatImplementsICoupon塞进其中。但是IList<Coupon>不能接受,因为SomeEvilTypeThatImplementsICoupon并不是从Coupon派生的。请参阅http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html来讨论此可转换性问题,尽管上下文稍有不同,请参阅此处的Eric Lippert文章链接。)

(相反,您的第一个代码段显式构造了一个List<ICoupon>,其中可以包含实现ICoupon的任何内容,然后将一些Coupon对象放入该列表中。现在,如果接收者决定将SomeEvilTypeThatImplementsICoupon插入该列表中,那么一切都很好,因为List可以容纳任何ICoupon,而不仅仅是实际的Coupon对象。)

关于c# - 接口(interface)列表与派生类型列表-无法将表达式类型转换为返回类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1864080/

10-09 05:47