C# 得到警告';类型参数X隐藏接口X';

C# 得到警告';类型参数X隐藏接口X';,c#,asp.net,generics,interface,C#,Asp.net,Generics,Interface,这发生在VisualStudio2010中 我正在使用通用方法,基本上失去了我的智能感知,阻止了我继续这个项目的工作 我基本上有以下课程: public class SearchRepository : DataRepository<IAudit> { public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters) {

这发生在VisualStudio2010中

我正在使用通用方法,基本上失去了我的智能感知,阻止了我继续这个项目的工作

我基本上有以下课程:

public class SearchRepository : DataRepository<IAudit>
{
    public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters)
    {
        // CODE GOES HERE
    }

    public override bool Delete<TIAudit>(IAudit audit)
    {
        // CODE GOES HERE
    }
}
公共类SearchRepository:DataRepository
{
公共覆盖IEnumerable RetrieveAll(IAuditSearch搜索参数)
{
//代码在这里
}
公共覆盖布尔删除(IAudit审核)
{
//代码在这里
}
}
这继承自:

public abstract class DataRepository<T>
{
    public virtual IEnumerable<T> RetrieveAll<U>(U parameter1)
    {
        throw new NotImplementedException();
    }

    public virtual bool Delete<U>(U parameter1)
    {
        throw new NotImplementedException();
    }
}
公共抽象类数据存储库
{
公共虚拟IEnumerable RetrieveAll(U参数1)
{
抛出新的NotImplementedException();
}
公共虚拟布尔删除(U参数1)
{
抛出新的NotImplementedException();
}
}
所以Delete的工作方式正是我所期望的。我有智能感知,它编译正确。使用IAuditSearch时RetrieveAll无法正常工作。如果我把它改为TIAuditSearch,它会说我“没有合适的方法可以重写”

不确定我做错了什么,但它肯定对我不满意


已更新:已将顶部的Delete方法的虚拟对象更改为覆盖。这是一个错误。

您无法定义方法公共覆盖IEnumerable RetrieveAll(IAuditSearch searchParameters)

该方法仍必须使用U类型参数代替IAuditSearch。由调用方选择要传递的类型

您可能需要创建一个ISearch接口,并在基类上添加where U:ISearch,但即使这样,您的子类也需要接受所有ISearch实现,而不仅仅是IAuditSearch

最好的解决方案可能是定义一个IAuditSearch存储库,它定义了RetreiveAll方法

编辑:我看到问题变了。现在两种方法都有相同的问题;重写方法时不能指定要使用的接口,必须维护泛型类型参数

public override IEnumerable<T> RetrieveAll<U>(U parameter1)  { }

public override bool Delete<U>(U parameter1)  { }
public override IEnumerable RetrieveAll(U参数1){
公共覆盖布尔删除(U参数1){}
请注意,您也不能将where子句添加到方法中;这打破了传统。此外,我甚至不确定编译器是否允许您这样做。

您正在隐式隐藏(通过不重写)签名的方法

bool Delete<myType>(myType param) { ... }
bool Delete(myType参数){…}
您可以克服在派生类的Delete属性中引入“new”关键字的错误。这明确地隐藏了签名,让每个人都高兴,因为它说明了你的意图


请阅读Microsoft文档:。

不幸的是,我不太清楚确切的上下文,但我相信您的代码应该如下所示:

public interface IParameter<T> {
    bool Match(T entry);
}
public abstract class DataRepository<T, TParameter>
    where TParameter : IParameter<T> {
    public abstract IEnumerable<T> RetrieveAll(TParameter parameter1);
    public abstract bool Delete(TParameter parameter1);
}
//
public interface IAudit {/* ... */}
public interface IAuditSearch : IParameter<IAudit> {/* ... */}

public class SearchRepository : DataRepository<IAudit, IAuditSearch> {
    public override bool Delete(IAuditSearch parameter1) {
        // iterate by collection items using parameter matching
        // CODE GOES HERE (DELETE ALL FOUND ENTRIES)
    }
    public override IEnumerable<IAudit> RetrieveAll(IAuditSearch parameter1) {
        // iterate by collection items using parameter matching
        // CODE GOES HERE (RETURN ALL FOUND ENTRIES)
    }
}
其中GuidSearch和IDRangeSearch实现为:

public class GuidSearch : IAuditSearch {
    Guid ID;
    public GuidSearch(Guid id) {
        this.ID = id;
    }
    public bool Match(IAudit entry) {
        /* search implementation using ID(Guid)*/
        throw new NotImplementedException();
    }

}
public class IDRangeSearch : IAuditSearch {
    int StartID;
    int EndID;
    public IDRangeSearch(int startId, int endId) {
        this.StartID = startId;
        this.EndID = endId;
    }
    public bool Match(IAudit entry) {
        /* search implementation using ID range (StartID...EndID)*/
        throw new NotImplementedException();
    }
}

下面的代码会起作用吗

public class SearchRepository : DataRepository<IAudit, IAuditSearch>
{
    public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters)
    {
        // CODE GOES HERE
    }

    public override bool Delete<TIAudit>(IAudit audit)
    {
        // CODE GOES HERE
    }
}

public abstract class DataRepository<T, TSearch>
{
    public virtual IEnumerable<T> RetrieveAll(TSearch parameter1)
    {
        throw new NotImplementedException();
    }

    public virtual bool Delete(T parameter1)
    {
        throw new NotImplementedException();
    }
}
公共类SearchRepository:DataRepository
{
公共覆盖IEnumerable RetrieveAll(IAuditSearch搜索参数)
{
//代码在这里
}
公共覆盖布尔删除(IAudit审核)
{
//代码在这里
}
}
公共抽象类数据存储库
{
公共虚拟IEnumerable RetrieveAll(t搜索参数1)
{
抛出新的NotImplementedException();
}
公共虚拟布尔删除(T参数1)
{
抛出新的NotImplementedException();
}
}
因此,对于DataRepository的每个实例化,我们都声明结果类型(T)和搜索类型(TSearch)


-C

您的
virtuals
中没有实现
abstract
类型是否正确?我想你应该用
抽象
关键字来代替,因为我只展示了部分代码。摘要有8-10种方法。每个存储库只覆盖其中的一小部分。您的一个答案对您的问题有帮助吗?如果是这样的话,你应该接受这样的一个。它不会让我高兴,因为它破坏了类的多态性。现在,如果我有一个对重写类的引用,它的行为是新的,但是如果我将它强制转换为基类型,它的行为是旧的。一般来说,我不喜欢成员隐藏的
new
关键字。如果你想保持多态性,你只需要使用“override”关键字,就可以通过强制转换对象来访问基本方法。至于隐藏,我不知道有哪种模式可以说明,我相信这会显式地移除对基派生的访问。为什么?我很想听听别人的例子。我打错了虚拟机,它应该是覆盖的。我更新了上面的代码。这只会稍微改变答案,下面的安迪给出了正确的答案。请注意,这两种方法都适用。你只看到了第一个错误;修正后,第二个将进行维修。我应该抓住它的,安迪,如果我想把不同的参数传递给不同的方法呢?如果还有一个检索方法需要Guid类型的参数呢?@Cyfer13:我已经更新了我的答案,更详细地解释了我的想法。请查看并告知我此方法是否适合您的需要。我看到的最大问题是您需要验证搜索参数。如果是RetrieveAll(guid x,guid y),则您知道它们已输入两个值。如果它是一个搜索对象,您不能保证该对象内部不为空。所以你需要一种叫做iValidate的东西。
public class SearchRepository : DataRepository<IAudit, IAuditSearch>
{
    public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters)
    {
        // CODE GOES HERE
    }

    public override bool Delete<TIAudit>(IAudit audit)
    {
        // CODE GOES HERE
    }
}

public abstract class DataRepository<T, TSearch>
{
    public virtual IEnumerable<T> RetrieveAll(TSearch parameter1)
    {
        throw new NotImplementedException();
    }

    public virtual bool Delete(T parameter1)
    {
        throw new NotImplementedException();
    }
}