0

我正在学习存储库模式,以便可以将其应用于 WPF MVVM。我从 SO 上的另一篇文章中得到了这段代码......

public interface IRepository : IDisposable
{
    IEnumerable<T> GetAll<T>();
}

所以我试图通过以下方式让它为我工作......

class CustomersRepository : IRepository
{
    public IEnumerable<Models.Customer> GetAll<T>()
    {
        DataView results;

        // some DAL retrieval code

        foreach (DataRowView row in results)
        {
            yield return new Models.Customer(row["Label"].ToString());
        }
    }
}

通过从我的模型中调用方法...

public static IEnumerable<Customer> ReadCustomers()
{
    IRepository repository = new CustomersRepository();
    return repository.GetAll<Models.Customer>();
}

但我收到一个错误,“CustomersRepository 没有实现接口成员“IRepository.GetAll< T >()”。“CustomersRepository.GetAll< T >()”无法实现“IRepository.GetAll< T >()”,因为它没有具有匹配的返回类型 "System.Collections.Generic.IEnumerable< T >"


但是,如果我在接口的标识符中定义类型参数,然后从方法调用中删除类型参数......

public interface IRepository<T> : IDisposable
{
    IEnumerable<T> GetAll();
}

...并且我相应地调整了实现以及来自我的模型的调用...

class CustomersRepository : IRepository<Models.Customer>
{
    public IEnumerable<Models.Customer> GetAll()
    {
        // same body content
    }
}

...

public static IEnumerable<Customer> ReadCustomers()
{
    IRepository<Models.Customer> repository = new CustomersRepository();
    return repository.GetAll();
}

...然后它完美地工作!

我的问题是:

  1. 为什么它不能在我最初的尝试中隐式地转换收益回报?这是设计使然,还是我误解了类型参数的工作原理?
  2. 考虑到我想将 CustomersRepository 松散耦合到我的 Customer 模型,并考虑到 Model 表示单个数据实体,有没有比在我的 Customer 模型类中使用静态工厂方法更好的方法?
4

1 回答 1

3

您对 IRepository 的实现并未涵盖接口可能要求的所有可能性。该接口指定您有一个GetAll带有泛型类型参数的方法,该方法又返回相同类型的 IEnumerable。

通过使用 实现此接口public IEnumerable<Models.Customer> GetAll<T>(),无论类型参数是什么,您都将始终返回一个IEnumerable<Models.Customer>,它与接口签名不对应。

我认为你应该继续你的第二个实现,除非 aCustomersRepository能够返回除IEnumerable<Models.Customer>

如果是这种情况,您可以这样做:

public IEnumerable<T> GetAll<T>()
{
    if (typeof(T).Equals(typeof(Models.Customer)))
    {
        DataView results;
        // some DAL retrieval code

        foreach (DataRowView row in results)
        {
            yield return (T) new Models.Customer(row["Label"].ToString());
        }
    }
}
于 2013-04-03T14:18:38.017 回答