2011-03-14 74 views
1

你好,製作一個函數來計算元素在多個陣列

出於某種原因(我不能工作了),返回一個IList不斷返回null,當我在同一個稱呼它(即使更早的功能方法它返回一個空的ilist,但無論如何),所以我正在做一個函數,以接受多個ilists,然後輸出所有列表中的元素總數(忽略空列表以避免發生異常)。

到目前爲止,我有:

private int TotalItemsInLists(params IList[] lists) 
    { 
     int total = 0; 


     foreach (IList list in lists) 
      if (list != null) 
       total += list.Count; 

     return total; 
    } 

但引起在對params IList[] lists問題似乎並沒有被正確調用,因爲ILists是不同類型的所有列表。

任何人都知道我可以如何解決這個問題?

感謝, 哈利

編輯:這是一個調用它

private bool TooManyItems(Person person) 
    { 
     return TotalItemsInLists(jobService.BeingDevelopedBy(person), jobService.BeingTestedBy(person), 
           jobService.BeingFixedBy(person), quoteService.BeingProducedBy(person), 
           ticketService.BeingActivelyHandledBy(person), 
           ticketService.BeingTestedBy(person), 
           ticketService.AllAvailable(person)) > 10; 
    } 

下面是他們所謂的一種方法的一個例子的代碼(他們都非常相似,只是不同的數據庫和過濾器)

public IList<Ticket> BeingActivelyHandledBy(Person person) 
    { 
     return (from ticket in Query() 
       where ticket.Handler == person 
         && ticket.Status == TicketStatus.Open 
         && ticket.Release == null 
       select ticket).ToList(); 
    } 
+1

你能調用張貼到你的方法 – Stefan 2011-03-14 10:16:19

+0

你能提供一個代碼示例和exptected結果呢? – 2011-03-14 10:16:40

+0

列出你傳遞的參數被聲明爲泛型?我的意思是列表 userList =新列表();? – 2011-03-14 10:17:57

回答

1

你必須輸入轉換爲IList

TotalItemsInLists((IList)jobService.BeingDevelopedBy(person), ... 
+1

沒有任何保證,列表甚至會實現非通用IList。 IList 保證ICollection ,IEnumerable 和IEnumerable,就是這樣。 – 2011-03-14 10:38:25

+0

是真的,我認爲Øyvind的建議返回列表,而不是IList 是最好的答案 – Stefan 2011-03-14 10:42:53

+0

這根本不能解決問題,也就是說,該方法給出IList 多個實例,其中T是不同的,因此解決方案是將它們轉換爲非通用接口,唯一保證工作的接口是IEnumerable。 (); – 2011-03-15 02:25:28

1

如果您IList<T> s爲實現ICollection(這是可能的,因爲大多數在實現IList<T>首創置業集合類也實現ICollection),那麼你可以簡單地轉換爲ICollection,雖然你將失去所有對象類型安全。

private int TotalItemsInLists(params object[] lists) 
{ 
    int total = 0; 

    // this casts each object implicitly to ICollection 
    foreach (ICollection list in lists) 
     if (list != null) 
      total += list.Count; 

    return total; 
} 

如果沒有,那麼你需要回到非通用IEnumerable和使用Cast<object>

private int TotalItemsInLists(params IEnumerable[] lists) 
{ 
    int total = 0; 

    foreach (IEnumerable list in lists) 
     if (list != null) 
      total += list.Cast<object>().Count(); 

    return total; 
} 
+0

Casting 應該是list.Cast ().Count(); – 2011-03-14 10:55:43

+0

@Darius:謝謝 – thecoop 2011-03-14 11:49:51

1

我認爲你能做的唯一的事情就是改變方法接受非通用IEnumerable類型。

private int TotalItemsInLists(params IEnumerable[] lists) 
{ 
    int total = 0; 

    foreach (var list in lists) 
     if (list != null) 
      total += list.Count(); 

    return total; 
} 

如果性能成爲一個問題,你可以在迴路中的快速檢查,如果該類型也是一個通用的或者非泛型ICollection的,直接讀取其Count屬性。

+0

爲什麼要做if(list!= null)? list.Count()是一個擴展方法,不需要額外的if。 – 2011-03-14 10:39:22

+0

如果'source'爲空,'Count()'拋出一個ArgumentNullException – thecoop 2011-03-14 10:41:55

+0

即使它不是擴展方法的必需條件,所有的Linq擴展方法都拋出ArgumentNullExceptions。 Count()也不例外(赦免雙關語)。 – 2011-03-14 10:42:44

1

如果你有你的列表生成方法返回例如List<Ticket>而不是IList<Ticket>它應該工作得很好,因爲List<T> implements IList

1

從本質上講,你的代碼不起作用的原因是因爲通用IList<T>實現非通用IList接口(這只是巧合List<T>恰好實現兩個接口)。

看來你所傳遞參數的靜態類型都是IList<SomeThing>,所以你明確的是不會起作用的。

一種解決方法是僅依靠經典的IEnumerable接口,並在方法本身中完成所有工作,即找出獲取每個子序列數的最快方法。

下面是一個未經測試的樣本:

private static int TotalItemsInLists(params IEnumerable[] lists) 
{ 
    if(lists == null) 
     throw new ArgumentNullException("lists"); 

    return lists.Sum(l => l == null ? 0 : GetCount(l));  
} 

private static int GetCount(IEnumerable source) 
{ 
    var collection = source as ICollection; 
    if (collection != null) 
     return collection.Count; 

    var genCollType = source.GetType().GetInterfaces() 
         .FirstOrDefault 
         (i => i.IsGenericType 
         && i.GetGenericTypeDefinition() == typeof(ICollection<>)); 

    if (genCollType != null) 
     return (int)genCollType.GetProperty("Count").GetValue(source, null); 

    return source.Cast<object>().Count(); 
} 
+0

爲什麼不在第一個函數中返回lists.Sum(x => x.Count())? – 2011-03-14 10:42:08

+0

@Saeed:那不行; 「計數」是爲IEnumerable 定義的。記住,我們在這裏討論不同類型的序列。但有點遺憾,IEnumerable沒有'Count()'擴展名。 – Ani 2011-03-14 10:43:37

+0

謝謝,你是對的Ani。 – 2011-03-14 10:46:27

相關問題