开发者

How can I use linq extensions without lambda?

开发者 https://www.devze.com 2023-03-08 15:38 出处:网络
This example is purely for learning, otherwise I would have used Lambda expressions right away. I would like to try and use the Where() extension method without lambda just to see how it would look,

This example is purely for learning, otherwise I would have used Lambda expressions right away.

I would like to try and use the Where() extension method without lambda just to see how it would look, but I can't figure out how to get it to compile and work properly. The example makes no sense so don't bother trying to figure out any logic to it.

I basically just want to know if it is possible to use extensions methods without using lambda (for learning purposes only) and how that would look like in code.

What I'm getting confused with is the Where() condition takes in a Func<int,bool>, but the method returns an IEnumerable<int>? The way the Func is defined, it takes in one int and returns a bool. It would make more sense to me if this was Func<int, bool, IEnumberable<string>>

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

namespace Delegates
{
    public class Learning
    {
        /// <summary>
        /// Predicates - 开发者_JAVA百科specialized verison of Func
        /// </summary>
        public static void Main()
        {
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            IEnumerable<int> result = list.Where(someFunc.Invoke(1));

        }


        static IEnumerable<int> greaterThanTwo(int arg, bool isValid)
        {
              return new List<int>() { 1 };
        }

    }
}

Updated Code

public class Learning
    {
        /// <summary>
        /// Predicates - specialized verison of Func
        /// </summary>
        public static void Main()
        {
            // Without lambda
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            // predicate of type int
            IEnumerable<int> result = list.Where(someFunc);

        }


        static bool greaterThanTwo(int arg, bool isValid)
        {
            return true;
        }

    }

I get the following error:

No overload for 'greaterThanTwo' matches delegate 'System.Func'


Where takes a function that accepts a single element (in this case, int) as a parameter, and a boolean as its return type. This is called a predicate - it gives a "yes" or "no" answer that can be applied over and over again to a sequence of elements of the same type.

You went wrong at the greaterThanTwo function - it takes two arguments, not one - and returns an IEnumerable<int> - so it's totally incompatible with Func<int, bool>. It should take an int and return a bool - again, this is a predicate (see above).

Once you sort that out, your other problem is Invoke - you aren't invoking anything - you're handing off a delegate (pointer) to a method, and the guts inside of Where will take care of invoking it when it needs.

Try this:

static bool greaterThanTwo(int arg)
{
    return (arg > 2);
}

//snip

Func<int, bool> someFunc = greaterThanTwo;
IEnumerable<int> result = list.Where(someFunc);


The definition Func<T, TResult> defines a delegate that takes a single parameter of type T and returns a result of type TResult. Linqs Where clause is defined (indirectly via an extension method) against an IEnumerable<T> and takes a parameter (the basic version of Where) of type Func<T, bool> which basically says the function must take a parameter of the type of the IEnumerable and return a bool value.

To make your example work:

bool greaterThanTwo(int arg)
{
    // this needs to be a boolean operation against the arg
    return arg > 2;
}

// and invoke like
list.Where(greaterThanTwo);


Func<int, bool> means that you have a function that takes in an int, and returns a bool. If you want to take more arguments into your function, you can list them out, however the last generic type that you define is the return type of that function. Your method would look something like this if you wanted to define it as a Func, Func<int, bool, IEnumerable<int>> Your function should look something like this.

namespace Delegates
{
    public class Learning
    {
        /// <summary>
        /// Predicates - specialized verison of Func
        /// </summary>
        public static void Main()
        {
            List<int> list = new List<int> { 1, 2, 3 };

            Func<int, bool> someFunc = greaterThanTwo;
            IEnumerable<int> result = list.Where(someFunc);

        }


        static bool greaterThanTwo(int arg)
        {
              return (arg > 2);
        }

    }
}


The Where() function executes the lambda once for every item. If you want to return, say a List<int> you would use Aggregate() instead which provides that functionality. But Where() automatically adds or doesn't add the item based on the boolean return value of your lambda.

0

精彩评论

暂无评论...
验证码 换一张
取 消