收到警告,';类型参数X隐藏接口X';

本文关键字:隐藏 接口 类型参数 警告 | 更新日期: 2023-09-27 18:27:52

这种情况发生在Visual Studio 2010中。

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

我基本上有以下课程:

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
    }
}

这继承自:

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();
    }
}

所以Delete的工作方式正是我所期望的。我有智能,它编译正确。RetrieveAll使用IAuditSearch无法正常工作。如果我将其更改为TIAuditSearch,那么它会说我"没有合适的方法可以覆盖"。

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

UPDATED:已将虚拟更改为覆盖顶部的Delete方法。那是个错误。

收到警告,';类型参数X隐藏接口X';

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

bool Delete<myType>(myType param) { ... }

您可以克服在派生类的Delete属性上引入"new"关键字的错误。这明确地隐藏了签名,让每个人都很高兴,因为它说明了你的意图。

阅读Microsoft文档,网址:http://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspx.

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

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

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

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

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

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

请注意,您也不能将where子句添加到方法中;这打破了利斯科夫替代原则。此外,我甚至不确定编译器是否允许您这样做。

下面的代码会起作用吗?

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();
    }
}

因此,对于DataRepository的每个实例化,我们都声明结果类型(T)和搜索类型(TSearch)。

-C

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

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)
    }
}

不同的IAuditSearch实现将包含"按不同参数搜索"逻辑:

var guidSearchResult = repository.RetrieveAll(
    new GuidSearch(new Guid("00000000-0000-0000-0000-000000000000")));
var idRangeSearchResult = repository.RetrieveAll(
    new IDRangeSearch(1000, 2000));

其中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();
    }
}