2008-08-23 106 views
8

什么是在列表中找到某些东西的最佳方式?我知道LINQ有一些很好的技巧,但我们也得到C#2.0的建议。让我们为这个通用的代码模式获得最好的重构。最干净的方式来查找列表中的匹配

目前我使用这样的代码:

// mObjList is a List<MyObject> 
MyObject match = null; 
foreach (MyObject mo in mObjList) 
{ 
    if (Criteria(mo)) 
    { 
     match = mo; 
     break; 
    } 
} 

// mObjList is a List<MyObject> 
bool foundIt = false; 
foreach (MyObject mo in mObjList) 
{ 
    if (Criteria(mo)) 
    { 
     foundIt = true; 
     break; 
    } 
} 

回答

14

@ Konrad:那你怎么用它?假设我想将mo.ID与magicNumber匹配。

在C#2.0中,你会写:

result = mObjList.Find(delegate(int x) { return x.ID == magicNumber; }); 

3.0知道lambda表达式:

result = mObjList.Find(x => x.ID == magicNumber); 
1

将代码放在一个方法,你保存的临时和break(你回收的代码,作为奖励) :

T Find<T>(IEnumerable<T> items, Predicate<T> p) { 
    foreach (T item in items) 
     if (p(item)) 
      return item; 

    return null; 
} 

...但当然这个方法已经存在,无论如何为列表,即使在.NET 2.0。

4

使用Lambda表达式:

List<MyObject> list = new List<MyObject>(); 

// populate the list with objects.. 

return list.Find(o => o.Id == myCriteria); 
1

显然匿名的性能损失代表相当重要。

测试代码:

static void Main(string[] args) 
    { 
     for (int kk = 0; kk < 10; kk++) 
     { 
      List<int> tmp = new List<int>(); 
      for (int i = 0; i < 100; i++) 
       tmp.Add(i); 
      int sum = 0; 
      long start = DateTime.Now.Ticks; 
      for (int i = 0; i < 1000000; i++) 
       sum += tmp.Find(delegate(int x) { return x == 3; }); 
      Console.WriteLine("Anonymous delegates: " + (DateTime.Now.Ticks - start)); 


      start = DateTime.Now.Ticks; 
      sum = 0; 
      for (int i = 0; i < 1000000; i++) 
      { 
       int match = 0; 
       for (int j = 0; j < tmp.Count; j++) 
       { 
        if (tmp[j] == 3) 
        { 
         match = tmp[j]; 
         break; 
        } 
       } 
       sum += match; 
      } 
      Console.WriteLine("Classic C++ Style: " + (DateTime.Now.Ticks - start)); 
      Console.WriteLine(); 
     } 
    } 

结果:

Anonymous delegates: 710000 
Classic C++ Style: 340000 

Anonymous delegates: 630000 
Classic C++ Style: 320000 

Anonymous delegates: 630000 
Classic C++ Style: 330000 

Anonymous delegates: 630000 
Classic C++ Style: 320000 

Anonymous delegates: 610000 
Classic C++ Style: 340000 

Anonymous delegates: 630000 
Classic C++ Style: 330000 

Anonymous delegates: 650000 
Classic C++ Style: 330000 

Anonymous delegates: 620000 
Classic C++ Style: 330000 

Anonymous delegates: 620000 
Classic C++ Style: 340000 

Anonymous delegates: 620000 
Classic C++ Style: 400000 

在每种情况下,使用匿名委托比其他方式更慢的约100%。

+1

不,这里的性能不是使用委托。你的算法功能根本不同,第一种方法有渐近运行时O(n^2),而第二种方法有运行时O(n)。这与委托没有任何关系,而是在这种情况下使用`Find`功能。 – 2008-11-04 07:37:09

相关问题