结果只公开接口的一个子集

本文关键字:一个 子集 接口 结果 | 更新日期: 2023-09-27 17:50:15

我正在使用实体框架6,我的一个函数将返回Database.SqlQuery的输出,这将是DbRawSqlQuery<TElement>。我希望我的类的接口不依赖于实体框架,所以我不想直接返回DbRawSqlQuery<TElement>,但我也想暴露IEnumerable<T>IListSource接口。

我知道c#没有接口的"duck typing",所以我不能只做

interface IQueryResult<out T> : IEnumerable<T>, IListSource
{    
}
//Elsewhere
public IQueryResult<T> RunQuery<T>()
{
    return this.Database.SqlQuery<T>(GetQuery());
}

我想我必须使用某种包装器来解决这个问题,但是有其他选择吗?

结果只公开接口的一个子集

下面是如何使用包装器类解决此问题的示例

public interface IQueryResult<out T> : IEnumerable<T>, IListSource
{    
}
internal class QueryResultWrapper<T> : IQueryResult<T>
{
    private readonly DbRawSqlQuery<T> _source;
    public QueryResultWrapper(DbRawSqlQuery<T> source)
    {
        _source = source;
    }
    public bool ContainsListCollection
    {
        get { return ((IListSource)_source).ContainsListCollection; }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)_source).GetEnumerator();
    }
    public IEnumerator<T> GetEnumerator()
    {
        return _source.GetEnumerator();
    }
    public IList GetList()
    {
        return ((IListSource)_source).GetList();
    }
}

然后将调用方法修改为

public IQueryResult<T> CallStoredProcedure<T>(string query)
{
    return new QueryResultWrapper<T>(this.Database.SqlQuery<T>(query));
}