接口中定义的方法不能从另一个接口中使用 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;
}
我收到两个错误
'IEntity' 不包含 'isNew' 的定义,并且找不到接受类型 'IEntity' 的第一个参数的扩展方法 'isNew'(您是否缺少 using 指令或程序集引用?)
'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();
}
我正在使用 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;
}
我收到两个错误
'IEntity' 不包含 'isNew' 的定义,并且找不到接受类型 'IEntity' 的第一个参数的扩展方法 'isNew'(您是否缺少 using 指令或程序集引用?)
'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();
}