2015-06-10 52 views
3

我在將謂詞傳遞給另一個函數時遇到了問題。此謂詞將作爲試圖調用第二個函數的參數傳入。以下是一段代碼片段。傳遞作爲參數傳入的謂詞

public IEnumerable<ViewModel> BuildModel<TPart, TRecord>(Expression<Func<TRecord, bool>> predicate) 
       where TPart : ContentPart<TRecord> 
       where TRecord : ContentPartRecord 
      { 
       IEnumerable<ReportPart> items = GetList<ReportPart, ReportRecord>(predicate); 

這個問題是謂語參數,在調用GetList()它使示數,稱呼叫有一些無效參數。在獲取列表電話是:

public IEnumerable<TPart> GetList<TPart, TRecord>(Expression<Func<TRecord, bool>> predicate) 
      where TPart : ContentPart<TRecord> 
      where TRecord : ContentPartRecord 

我一直在試圖改變參數一堆不同的方式試圖得到這個工作,但我還沒有成功。也許我不明白爲什麼編譯器認爲'predicate'與GetList()期望的不同。

編輯:詳細信息

ReportPart : ContentPart<ReportRecord> 

ReportRecord : ContentPartRecord 

ContentPart和ContentPartRecord都是基本類

呼叫者BuildModels

List<ReportViewModel> model = _service.BuildReports<ReportPart, ReportRecord>(x => x.Id == 1).ToList(); 

BuildModels

public IEnumerable<ReportViewModel> BuildReports<TPart, TRecord>(System.Linq.Expressions.Expression<Func<TRecord, bool>> predicate) 
      where TPart : ContentPart<TRecord> 
      where TRecord : ContentPartRecord 
{ 
      List<ReportViewModel> model = new List<ReportViewModel>(); 
      IEnumerable<ReportPart> reportParts = GetList<ReportPart, ReportRecord>(predicate); 
      //do some stuff with reportParts 
      return model; 
    } 
} 

的GetList

public IEnumerable<TPart> GetList<TPart, TRecord>(System.Linq.Expressions.Expression<Func<TRecord, bool>> filter) 
      where TPart : ContentPart<TRecord> 
      where TRecord : ContentPartRecord 
     { 
      return filter == null ? 
       Services.ContentManager.Query<TPart, TRecord>().List() : 
       Services.ContentManager.Query<TPart, TRecord>().Where(filter).List(); 
     } 
+0

您能否發佈精確的錯誤信息?你也可以發佈「ReportPart」和「ReportRecord」的繼承層次嗎? – Enigmativity

+0

根據您的錯誤消息,問題是由傳遞給BuildModel的參數引起的。你打電話過得怎麼樣? –

+0

它不會錯誤地調用'GetList'。它錯誤地調用了'BuildModel',你在這裏沒有顯示。 –

回答

2

沒有a good, minimal, complete code example,這是不可能確切知道你的問題的最佳解決方法是什麼,假設一個存在於所有。

也就是說,方差問題一般有兩種形式:1)你在做什麼是真正的錯誤,編譯器爲您節省,和2)你在做什麼是不正確可證明,所以你必須向編譯器保證你知道你在做什麼。

如果您處於第一類,則全部丟失。你無法得到這個工作。

但是,如果你在第二類是,你可以得到你的電話在一個新的,與調用方法的要求相適應包裝原始謂詞的工作:

IEnumerable<ReportPart> items = 
    GetList<ReportPart, ReportRecord>(r => predicate((TRecord)r)); 


儘管如此,儘管有可能以這種方式編寫代碼有一些重要原因,但考慮到目前爲止顯示的一小段代碼,並不清楚爲什麼要嘗試使用泛型謂詞並強制它進入特定類型。

根據什麼在代碼的其餘部分是真正回事,一對普通的方法,這樣會更好地工作,你要麼1)去完全通用的(即不調用強制類型ReportRecordGetList()),或2)你根本不用打擾通用類型(即從BuildModel()方法中省略TPartTRecord)。

1例):例2)

public IEnumerable<ViewModel> BuildModel<TPart, TRecord>(
    Expression<Func<TRecord, bool>> predicate) 
     where TPart : ContentPart<TRecord> 
     where TRecord : ContentPartRecord 
{ 
    IEnumerable<TPart> items = GetList<TPart, TRecord>(predicate); 
} 

public IEnumerable<ViewModel> BuildModel(
    Expression<Func<ReportRecord, bool>> predicate) 
{ 
    IEnumerable<ReportPart> items = GetList<ReportPart, ReportRecord>(predicate); 
} 

混合和匹配,就算你能得到它的正常工作,往往是一個在體系結構中存在一個更基本的問題,那就是泛型被用在不應該被使用的地方,或者它們應該沒有被利用。


如果上述不能讓你回到正軌,你應該通過提供一個最小的,完整的代碼示例來改善問題。

+0

更改爲示例二來使其工作。我對它做了很多修改,這就是爲什麼你看到了通用和非通用的原因。例二實際上是我想要實現的。 – Adam