2011-03-14 73 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

相关问题