1

我有一种情况让我感到困惑,希望能得到一些帮助。在下面的代码中,FindById 方法无需强制转换即可工作,但 UpdatedAuditedEntity 调用不会。注意:

  1. AuditedEntity 派生自 Entity
  2. 将 auditedEntity 转换为 Entity 不起作用,仅转换为 T 有效。

对我在这里缺少的任何见解将不胜感激。起初我认为这与方差有关,但正如我上面提到的,我尝试向下投射但没有成功。

    public class NHibernateRepository<T> : NHibernateBase,
    IRepository<T> where T : Entity
{

    public IEnumerable<T> FindAll(Expression<Func<T, bool>> predicate)
    {
        var query = GetQuery(predicate);
        return Transact(() => query.ToList());
    }

    public T FindById(int id)
    {
        // TODO: Why does this work when below doesn't
        return FindAll(e => e.Id == id).FirstOrDefault();
    }

    private T UpdateAuditedEntity(T item)
    {
        var auditedEntity = item as AuditedEntity;

        if (auditedEntity == null) return item;

        auditedEntity.DateModified = DateTime.UtcNow;

        // TODO: figure out why this cast is necessary
        return auditedEntity as T;
    }
4

2 回答 2

2

这是必要的,因为尽管 AuditedEntity 和 T 都是从 Entity 派生的,但 AuditedEntity 可能不会继承 T 表示的任何类型。

例如,假设您创建了一个直接继承实体的类型“OtherEntity”。一个实例 NHibernateRepository<OtherEntity>将使 UpdateAuditedEntity 返回一个 AuditedEntity,它不继承 OtherEntity - 因此返回的类型将无效。

于 2012-05-16T14:04:26.207 回答
2

AuditedEntity 派生自 Entity

好的,但是在这个泛型类中,T是. 编译器并不关心你是通过强制转换创建的——实际上,这里可能会有自定义转换在做意想不到的事情——所以不允许你从请求.EntityauditedEntityitemAuditedEntityT

在这个特定的方法中,因为itemauditedEntity同一个对象,你可以这样做

return item;

作为最后一条语句,UpdateAuditedEntity编译器会很高兴。

于 2012-05-16T14:10:04.380 回答