我在尝试创建一个通用接口时收到此错误,该接口有两个名称相同但签名不同的方法。 知道我做错了什么以及如何解决它?
类型'XXX.Interfaces.IRepository'已经定义了一个名为'Delete'的成员,其参数类型相同
public interface IRepository<T> : IRepositoryReadOnly<T>
{
void Add(T entity);
void Update(T entity);
void Delete(T id);
void Delete(T entity);
void Save();
}
答案 0 :(得分:4)
它们具有相同的签名(参数类型是重要的,而不是参数名称)。
如果您的所有实体都有ID标识字段,您可能希望将其中一个删除方法更改为
void Delete(int id);//or another type, if that's a GUID, a string...
但是为了能够在“通用环境”中实现该删除功能,您可能需要让所有实体实现一个接口(如果您想避免,它们可以从实现该接口的公共基本抽象类继承)写太多代码)。
如果您有一个基本的Repository抽象类,使用公共和/或抽象和/或虚拟方法(假设您有,假设您不想为所有实体绝对实现Delete(int id)
那将是必需的)。
public interface IHasId {
int Id {get;set;}
}
并添加约束
public interface IRepository<T> : IRepositoryReadOnly<T> where T : class, IHasId
答案 1 :(得分:3)
您的方法没有不同的签名。方法参数的名称无关紧要,只有类型。
如何在调用代码时指定要调用的方法?
您的id
也是[{1}}类型,还是属于T
类型?
int
答案 2 :(得分:2)
参数名称不计入签名。
如果我拨打repository.Delete(5)
,你怎么知道要运行哪种方法?
您可能想要重命名它们。例如,DeleteById(T id)
和DeleteEntity(T entity)
。
答案 3 :(得分:2)
方法的签名包括方法的名称和 每种形式的类型和种类(价值,参考或输出) 参数,按从左到右的顺序考虑。
从MSDN复制。
因此,您的Delete(T)
方法对这两种方法都具有相同的签名。您可以将签名更改为此(或将id
改为int
/ long
):
void Delete(object id);
void Delete(T entity);
答案 4 :(得分:1)
您可能需要引入另一个类型参数contravariant
,以将其反映为不同的签名,例如X
public interface IRepository<T, in X> : IRepositoryReadOnly<T>
{
void Add(T entity);
void Update(T entity);
void Delete(X id);
void Delete(T entity);
void Save();
}
答案 5 :(得分:1)
试试这个:
public interface IRepository<T> : IRepositoryReadOnly<T>
{
void Add(T entity);
void Update(T entity);
void Delete(T id);
void Delete(T entity) where T : <EntityType>;
void Save();
}
答案 6 :(得分:0)
您有两种方法(删除)具有相同的签名。你应该删除其中一个。
答案 7 :(得分:0)
你可能想要
public interface IRepository<T> : IRepositoryReadOnly<T>
{
void Add(T entity);
void Update(T entity);
void Delete(object id);
void Delete(T entity);
void Save();
}
为什么要通过ID传递T in来删除? T将是实体类型