在某些情况下,在一般方法上显式转换为T.

时间:2012-05-16 13:55:50

标签: generics c#-4.0

我的情况令我感到困惑,希望得到一些帮助。在下面的代码中,FindById方法可以在不必转换返回的情况下工作,但不能使用UpdatedAuditedEntity调用。请注意:

  1. AuditedEntity派生自实体
  2. 将auditedEntity转换为实体不起作用,仅转换为T工作。
  3. 对于我在这里缺少的任何见解将不胜感激。起初我认为它与方差有关,但正如我上面提到的那样,我尝试了没有成功的铸造。

        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;
        }
    

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

  

AuditedEntity派生自实体

好的,但在此通用类中,T属于Entity任意派生词。编译器并不关心你auditedEntity是通过投射item来创建的 - 事实上,可能会有自定义转换在这里做意想不到的事情 - 所以不允许你返回一个变量键入作为AuditedEntity来自请求T的方法。

在这种特定的方法中,由于itemauditedEntity 相同的对象,您可以这样做

return item;

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