2012-11-02 86 views
0

我嘗試創建的泛型方法的簽名有問題。C#通用方法聲明

的類是如下:

public class MarketDataRepository : IRepository 
{ 
    MarketWatchEntities _dbContext = new MarketWatchEntities(); 

    public MarketDataRepository(){} 

    public MarketDataRepository(MarketWatchEntities dbContext) 
    { 
     _dbContext = dbContext; 
    } 

    public IEnumerable<T> GetMarketData<T>(DateTime startDateTime, DateTime endDateTime) where T : MarketDataPoint 
    { 
     return _dbContext.MarketDataPoints.Where(x => x.ReferenceDateTime >= startDateTime && x.ReferenceDateTime <= endDateTime).ToList(); 
    } 
} 

public interface IRepository 
{ 
    IEnumerable<T> GetMarketData<T>(DateTime startDateTime, DateTime endDateTime) where T : MarketDataPoint; 
} 

其他信息:
MarketWatchEntities延伸DbContext(由實體框架生成)。

我得到這個編譯時異常:

Cannot implicitly convert type 'System.Collections.Generic.List<MarketWatcher.Domain.MarketDataPoint>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?) 

我原以爲這是我的約束TMarketDataPoint繼承的基礎上確定。所以,我認爲我將能夠返回MarketDataPointIEnumerable

任何指針,以上哪些是錯誤的,我應該做什麼,而不是非常感激!

解決方案(謝謝大家):

public class MarketDataMarketDataRepository : IMarketDataRepository 
{ 
    MarketWatchEntities _dbContext = new MarketWatchEntities(); 

    public MarketDataMarketDataRepository(){} 

    public MarketDataMarketDataRepository(MarketWatchEntities dbContext) 
    { 
     _dbContext = dbContext; 
    } 

    public IQueryable<T> GetMarketData<T>(DateTime startDateTime, DateTime endDateTime) where T : MarketDataPoint 
    { 
     return _dbContext.MarketDataPoints.Where(x => x.ReferenceDateTime >= startDateTime && x.ReferenceDateTime <= endDateTime).OfType<T>(); 
    } 
} 
+1

爲什麼您將GetMarketData 方法放入您的IRepository接口?聞起來像是在你的設計中休息 – KroaX

+0

你絕對是對的。這將從IRepostory擴展爲IMarketDataRepository。 –

回答

5

這不工作的原因是因爲T可以MarketDataPoint更具體

如果您已經從MarketDataPoint派生並有人撥打GetMarketData<S>,類S你怎麼給他們一個IEnumerable<S>當所有你是MarketDataPoint個集合?

編輯:馬特本人指出的那樣,你可以鏈OfType<T>()的話,可以剔除掉非T元素返回正確類型的IEnumerable

return _dbContext.MarketDataPoints 
    .Where(
     x => x.ReferenceDateTime >= startDateTime && 
     x.ReferenceDateTime <= endDateTime) 
    .OfType<T>() 
    .ToList(); 
+0

是的,你說得很對。我想我可能需要稍後擴展這個方法來使用typeof(T),所以我想在前面得到聲明,但現在我可以按照你的建議去做。 –

+0

@Matt我的第一個答案是錯誤的,我改變了它,但現在,如果你只有'MarketDataPoint's來處理,那麼只是使該方法非通用。 – Rawling

+0

@Rawling:通過檢查表中的元素是T型還是IsAssigableFrom(typeof(T))。這樣,此方法將始終返回所請求的類型T並篩選出錯誤的類型。 – LightStriker

0

如果您按照錯誤並手動投它IEnumerable<T>

public IEnumerable<T> GetMarketData<T>(DateTime startDateTime, DateTime endDateTime) where T : MarketDataPoint 
{ 
    return (IEnumerable<T>)_dbContext.MarketDataPoints.Where(x => x.ReferenceDateTime >= startDateTime && x.ReferenceDateTime <= endDateTime).ToList(); 
} 

的問題是,IEnumerable<MarketDataPoint>是不一樣的IEnumerable<T>

+0

是的 - 這是可行的。謝謝,不知道爲什麼我沒有想到這一點;-) –

+1

哇...怎麼了downvote?我錯過了什麼嗎? – LightStriker

+0

@LightStriker如果您將_derived從MarketDataPoint調用爲'T',則在運行時將失敗。 (我沒有DV你,因爲我自己犯了同樣的錯誤!) – Rawling