扩展方法问题

时间:2013-02-23 16:55:17

标签: c# .net c#-4.0

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace LambdaExtensionEx
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] myStrngs = new string[] { "Super","Simple","Okay"};
            IEnumerable<string> criteraStrngs = myStrngs.WhereSearch<string>(delegate(string s)
            {
                return s.StartsWith("s");
            });

            string s1 = "dotnet";
            int count = s1.GetCount();

            Console.ReadLine();
        }
    }

    public static class MyExtension
    {
        public delegate bool Criteria<T>(T Value);

        public static IEnumerable<T> WhereSearch<T>(this IEnumerable<T> values, Criteria<T> critera)
        {
            foreach (T value in values)
                if (critera(value))
                    yield return value;
        }

        public static int GetCount(this string value)
        {
            return value.Count();
        }
    }
}

我可以调用GetCount扩展方法,我得到了结果&#39; count&#39;。但WhereSearch在任何时候都没有被调用而没有得到结果。我在做什么错误?

2 个答案:

答案 0 :(得分:5)

如果希望它被执行,您需要开始枚举WhereSearch函数返回的结果。原因是因为此函数yield returnsIEnumerable<T>。 C#编译器做的是构建一个状态机,并且在调用代码开始枚举结果之前不立即执行该函数。

例如:

// The function is not executed at this stage because this function uses 
// yield return to build an IEnumerable<T>
IEnumerable<string> criteraStrngs = myStrngs.WhereSearch<string>(delegate(string s)
{
    return s.StartsWith("s");
});
// Here we start enumerating over the result => the code will start executing
// the function.
foreach (var item in criteraStrngs)
{
    Console.WriteLine(item);
}

另一个例子是在结果上调用一些LINQ扩展方法,例如.ToList(),它实际上会枚举并调用函数:

IEnumerable<string> criteraStrngs = myStrngs.WhereSearch<string>(delegate(string s)
{
    return s.StartsWith("s");
})
.ToList();

有关延迟加载如何工作的详细信息,您可以查看following post

答案 1 :(得分:0)

您的扩展方法类没有多大意义 - 为什么不这样做呢?

 class Program
{
    static void Main(string[] args)
    {
        string[] myStrngs = new string[] { "Super", "Simple", "Okay" };
        IEnumerable<string> criteraStrngs = myStrngs.Where(x => x.StartsWith("s"));

        string s1 = "dotnet";
        int count = s1.Count();

        Console.ReadLine();

    }
}

正如Darin Dimitrov之前所述 - 你仍然需要枚举criteriaStrngs以获得结果 - 这就是原始代码的错误。

HTH