接口中定义的方法不能从另一个接口中使用 class

Methods defined in an interface can no be used from another class

我正在使用 Entity Framework 4.1 和代码优先方法。

我有以下界面

namespace BackupCore.Contracts
{
    public interface IEntity
    {
        DbSet getDbSet(BackupCoreContainer context);

        bool isNew() ;
    }
}

namespace BackupCore
{
    interface IDao<IEntity>
    {
        IEntity Save(IEntity ent);

        IQueryable<IEntity> GetAll();

        bool Delete(IEntity ent, out String errMsg);

        void SaveChanges();
    }
}

当尝试创建这样的摘要时 EntityDao...

using BackupCore.Contracts;

namespace BackupCore
{
    public abstract class EntityDao<IEntity> : IDao<IEntity> 
    {
        BackupCoreContainer unique;

        protected BackupCoreContainer Context
        {
            get
            {
                if (unique == null)
                {
                    unique = new BackupCoreContainer();
                }
                return unique;
            }
        }

        IEntity IDao<IEntity>.Save(IEntity ent)
        {
            bool isNew;
            bool success;

            isNew = ent.isNew();


            if (isNew)
            {
                ent.getDbSet(Context).Add(ent);
            }

            //Context.Entry(ent).State = (isNew) ? EntityState.Added : EntityState.Modified;

            SaveChanges();
            return ent;
        }

我收到两个错误

  1. 'IEntity' 不包含 'isNew' 的定义,并且找不到接受类型 'IEntity' 的第一个参数的扩展方法 'isNew'(您是否缺少 using 指令或程序集引用?)

  2. 'IEntity' 不包含 'getDbSet' 的定义,并且找不到接受类型 'IEntity' 的第一个参数的扩展方法 'getDbSet'(您是否缺少 using 指令或程序集引用?)

我想我在这里遗漏了一些非常 basic/obvious 的东西,但是是什么原因造成的,我该如何解决它

您的定义 public abstract class EntityDao<IEntity> : IDao<IEntity> 定义了一个名为 IEntity 的类型参数,它 隐藏了 您在别处定义的名为 IEntity 的接口。

为了避免混淆,John(Saunders,在他现已删除的回答中)正确地建议使用消除此类名称冲突的标准命名约定:使用 I 前缀接口名称和类型参数名称T。这给

public abstract class EntityDao<TEntity> : IDao<TEntity> 
{
    TEntity IDao<TEntity>.Save(TEntity ent)
    {
        bool isNew;
        bool success;

        isNew = ent.isNew();

        if (isNew)
        {
            ent.getDbSet(Context).Add(ent);
        }

        //Context.Entry(ent).State = (isNew) ? EntityState.Added : EntityState.Modified;

        SaveChanges();
        return ent;
    }
}

你会发现这样还是编译不通过。注意方法的参数不再是 IEntity 而是 TEntity。编译器还不知道为 TEntity 提供的类型参数将具有在 IEntity 上定义的成员。将这一事实通知编译器的机制称为 "generic type constraints";也就是说,您将类型参数限制为 IEntity 或实现 IEntity 的类型。这为编译器提供了这些成员可用的保证。

要应用约束,只需在 class 声明中添加一个 where 子句:

public abstract class EntityDao<TEntity> : IDao<TEntity>
    where TEntity : IEntity
{
    //...

不一定需要对 IDao<> 的定义进行这些更改,但是,为避免混淆,最好这样做:

interface IDao<TEntity>
{
    TEntity Save(TEntity ent);
    IQueryable<TEntity> GetAll();
    bool Delete(TEntity ent, out String errMsg);
    void SaveChanges();
}

最后,IDao<>的类型参数也不一定要加上类型约束,但是可以的。我更喜欢只在编译器严格需要的地方添加类型约束,但很多人宁愿在此处添加约束,因为它使代码的意图更清晰:

interface IDao<TEntity> where TEntity : IEntity
{
    TEntity Save(TEntity ent);
    IQueryable<TEntity> GetAll();
    bool Delete(TEntity ent, out String errMsg);
    void SaveChanges();
}