使用泛型的突破性错误

时间:2013-03-28 11:54:19

标签: c# .net generics

我正在尝试制作通用Repository pattern基类,其中将实现成员。这是一个代码:

public abstract class RepositoryBase<TEntity, TType> : IRepository<TEntity, TType>
    where TEntity : EntityBase<TType>
{
    public IAdNetMsSqlContext Context { get; set; }
    public DbSet<TEntity> DbSet { get; set; }

    public RepositoryBase(IAdNetMsSqlContext context)
    {
        Context = context;
        DbSet = context.Set<TEntity>();
    }

    public IQueryable<TEntity> Get(TType id)
    {
        //!!! Here is an error
        return DbSet.FirstOrDefault(e => e.Id == id);
    }
    ....
}

我收到错误:

   Error    1   Operator '==' cannot be applied to operands of type 'TType' and    `'TType' .... AdNet.Common.Base

在行中:

   return DbSet.FirstOrDefault(e => e.Id == id);

我不知道该怎么想。 TType肯定等于TType。

任何进步的Thx!

3 个答案:

答案 0 :(得分:7)

这里有两个问题:

  • IQueryable<TEntity>只返回一个FirstOrDefault时,您尝试返回TEntity,因此您应该更改返回类型
  • 您正在尝试使用==,这是不受限制的泛型。您可以将TType约束为一个类,此时它将执行引用相等,但考虑到您给出的示例,这可能不是您想要的。

鉴于这将被转换为SQL无论如何(所以你不必担心拳击的影响)我只是将其转换为使用Equals

public TEntity Get(TType id)
{
    return DbSet.FirstOrDefault(e => e.Id.Equals(id));
}

或者你不能首先使用DbSet<TEntity>.Find吗?

public TEntity Get(TType id)
{
    return DbSet.Find(id);
}

答案 1 :(得分:1)

您可能知道TType显然等于TType,但编译器不知道的是任何任意的,不受约束的TType是否会有==运算符(又名op_Equality)。

您可以使用Equals吗?

return DbSet.FirstOrDefault(e => e.Id.Equals(id));

答案 2 :(得分:0)

只是两个泛型都使用相同的名称:TType

从编译器的角度来看,它并没有意识到e.Id与id相同,而且很可能你可以编写一些使场景成为真的代码。

我假设TType的比较检查它在物理上是同一个对象而不是具有相同值的2个对象。如果将两者都转换为Object,则比较应该起作用