在列表中查找内容的最佳方法是什么? 我知道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;
    }
}

===============>>#1 票数:15 已采纳

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

在C#2.0中你会写:

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

3.0知道lambdas:

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

===============>>#2 票数:4

使用Lambda表达式:

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

// populate the list with objects..

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

===============>>#3 票数: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 票数: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%。

  ask by Nick translate from so

未解决问题?本站智能推荐:

3回复

在ASP.NET后端中找到方法

我正在重构部分代码,这是庞大,复杂的.Net项目的一部分。 有一段代码像 注意命令名称genius ,他编写了名为Update的代码。 由于项目规模巨大,您可以想象有多少种“更新”方法。 我需要非常糟糕地找到该方法,有什么方法可以获取调用堆栈或其他东西?
1回复

如何从C#类方法中找到调用哪些方法 - 而不是在运行时

我有一个C#类,代码太多了,我想refactor它。 我想要做的是从所有public methods ,并为每个public methods构建一个tree ,显示从中调用类中的其他方法,然后从子类中调用哪些方法,依此类推。 这将使我能够看到哪些private methods仅属于一个p
5回复

在C#中重写此最佳/最惯用的方法

我有这个if-else语句可以做我想要的。 正如你应该能说的那样,它正在做的事情非常简单。 提到的enum是: 它非常简单,我确信有更简洁,更易读的方式来表达这一点。 注意如果不是因为默认情况下VS强加的荒谬的“每条一条线”规则,我可能不会那么烦恼。 例如在VB中,我可
2回复

打破类中所有依赖项的最简单,最快捷的方法

在使用遗留代码并尝试创建测试时,我经常从类或方法中分离出依赖关系,因此我可以使用模拟来为这些依赖项编写单元测试。 依赖关系通常以调用静态类和使用构造函数中的new关键字或该类中其他位置创建的对象的形式出现。 在大多数情况下,静态调用通过包装静态依赖项来处理,或者如果它以StaticCla
1回复

如何使它更干净

我有很大一部分这样的代码遍历数组 该代码段应采用网格的索引x和y 和 放在这样的字典里 我试图对其进行重构以使其更小或更清晰,但实际上,老实说,我找不到能够使大事情变小的好的解决方案。 有人能帮我吗 ?
1回复

如何在解决方案中找到相对于其位置名称而言不正确的所有命名空间?

我正在寻找一种在解决方案中查找所有错误名称空间的技术。 错误的命名空间是指与当前位置不同的所有命名空间。 例如:如果我有一个名为MyCompany.MyProject.Frontend的项目,并且在Controller文件夹下有一个类,则最终的命名空间应为: MyCompany.My
4回复

更干净的抽象方式

我正在重构一些旧代码,并对设计决策感到震惊 上面的抽象类具有抽象方法Step 1,Step 2和Step3。Step2始终需要调用方法2.1和2.2。 但是在当前设计中,步骤2.1和2.2并未声明为抽象,而是在每个继承的类中都已实现并调用了该步骤。 我打算通过将所有这些方法(包括2.
2回复

有没有什么可以使T4代码更干净...干净?

我有一个相当复杂的东西塞进T4模板。 基本上我采取类似的东西 {= foo =}更多文字... 并将其转换为类(视图),如下所示: 生成的代码当然要复杂得多。 无论如何,T4模板现在超过600行代码,并且真正变得难以管理。 我认为主要问题是混合代码和“内容”(即静
4回复

有没有更有效的方法基于现有列表和查找列表创建列表?

我有以下方法,该方法需要很长时间才能运行,并且希望获得一些帮助,以使其运行更快或更高效。 该方法的主要职责是获取从CSV文件创建的数据点列表,通过DataLoggerTagname属性将文件数据点的Name属性映射到标记名列表中的HistorianTagname属性,并从映射。 如果映射
1回复

如何安全,干净地重写关键/生产代码? [关闭]

我有一些关键的生产程序需要从头开始重写。 举一个简单的例子: 输入对象有太多的排列方式来彻底进行单元测试,我想要安全地使用它,因为这些例程每天都在大量使用。 所以,我的想法是: 1)将当前实现重命名并标记为过时。 2)如果有任何问题,写一个新的实现,然后再回到旧的实现(见