2013-04-03 22 views
0

我正在學習存儲庫模式,所以我可以將它應用於WPF MVVM。我得到了這片從SO另一郵編...無法隱式轉換爲IEnumerable <T> ...但我可以通過其他方式...爲什麼?

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 model類中使用靜態工廠方法更好的方法?

回答

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

很好的回答,與一個很好的例子...謝謝! – Heliac

+0

我對此感興趣,只是爲了確保我理解,您將轉換爲新模型的對象。通過在返回之前聲明(T)來通過哪個類型的客戶? – Derek

+0

@Derek,在這種情況下,我在檢查之前要確定'T'屬於'Models.Customer'類型。我只需在返回之前將它轉換爲T,否則編譯器會告訴我它無法將Models.Customer轉換爲T。 –

相關問題