不能隐式地转换为IEnumerable <t> ...但我可以反过来......为什么?</t>

时间:2013-04-03 13:56:50

标签: c# ienumerable repository-pattern

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

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&lt; T&gt;()“。”CustomersRepository.GetAll&lt; T&gt;()“无法实现”IRepository.GetAll&lt; T&gt;()“因为它没有匹配的返回类型”System.Collections.Generic.IEnumerable&lt; T&gt;“


但是,如果我在接口的标识符中定义了type参数,我将从方法调用中删除type参数...

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模型类中使用静态工厂方法更好的方法?

1 个答案:

答案 0 :(得分:3)

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

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

我认为你应继续进行第二次实施,除非CustomersRepository能够返回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());
        }
    }
}