【问题标题】:Brain-breaking error using generics [duplicate]使用泛型的脑裂错误[重复]
【发布时间】:2013-03-18 20:20:43
【问题描述】:

我正在尝试创建通用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。

感谢任何提前!

【问题讨论】:

标签: c# .net generics


【解决方案1】:

这里有两个问题:

  • FirstOrDefault 只会返回一个TEntity 时,您尝试返回IQueryable&lt;TEntity&gt;,因此您应该更改返回类型
  • 您正在尝试使用==,这在不受约束的泛型上是不允许的。您可以将 TType 约束为一个类,此时它将执行引用相等,但鉴于您给出的示例,这可能不是您想要的。

鉴于这无论如何都会被翻译成 SQL(所以你不必担心装箱的影响)我只是将其转换为使用 Equals

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

或者你不能一开始就使用DbSet&lt;TEntity&gt;.Find

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

【讨论】:

  • 非常感谢!这个有帮助。
【解决方案2】:

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

你能用Equals代替吗?

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

【讨论】:

    【解决方案3】:

    恰好两个泛型共享相同的名称:TType

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

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

    【讨论】:

      猜你喜欢
      • 2012-05-11
      • 2023-03-13
      • 1970-01-01
      • 2019-02-22
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      • 2021-04-22
      • 2018-07-29
      相关资源
      最近更新 更多