获得警告,'类型参数X隐藏接口X'

时间:2012-03-14 16:20:54

标签: c# asp.net generics interface

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

所以删除工作正是我期望它的工作方式。我有intellisense,它编译正确。使用IAuditSearch,RetrieveAll无法正常工作。如果我将其更改为TIAuditSearch,那么它说我“没有合适的方法来覆盖”。

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

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

4 个答案:

答案 0 :(得分:5)

您隐式隐藏(通过不覆盖)

的方法签名
bool Delete<myType>(myType param) { ... }

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

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

答案 1 :(得分:1)

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

该方法仍必须使用U type参数代替IAuditSearch。它由调用者选择要通过的类型。

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

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

编辑:我发现问题已经改变了。你现在在两种方法上都有同样的问题;您无法指定在重写方法时使用哪个接口,您必须维护泛型类型参数。

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

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

请注意,您不能在方法中添加where子句;这打破了Liskov Substitution Prinicple。另外我甚至不确定编译器会允许你这样做。

答案 2 :(得分:0)

不幸的是,确切的上下文对我来说并不十分清楚,但我相信你的代码应该是这样的:

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

答案 3 :(得分:0)

以下代码会改为吗?

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