接口中定义的方法不能从另一个类使用
本文关键字:另一个 不能 定义 方法 接口 | 更新日期: 2023-09-27 17:56:38
我正在使用实体框架 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;
}
我收到两个错误
- "IEntity"不包含"isNew"
的定义,并且找不到接受类型为"IEntity"的第一个参数的扩展方法"isNew"(您是否缺少使用指令或程序集引用?
"IEntity"不包含"getDbSet"的定义,并且找不到接受类型为"IEntity"的第一个参数的扩展方法"getDbSet"(您是否缺少使用指令或程序集引用?
我相信我在这里错过了一些非常基本/明显的东西,但是是什么导致了这种情况以及如何解决它
>您的定义public abstract class EntityDao<IEntity> : IDao<IEntity>
定义一个名为 IEntity
的类型参数,该参数隐藏您在其他地方定义的名为IEntity
的接口。
为了避免混淆,John(桑德斯,在他现已删除的答案中)正确地建议使用标准命名约定来消除这种名称冲突:使用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
上定义成员。 通知编译器这一事实的机制称为"泛型类型约束";也就是说,将类型参数约束为IEntity
或实现 IEntity
的类型。 这为编译器提供了这些成员可用的保证。
若要应用约束,只需将 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();
}