tags:

views:

70

answers:

5

I guess I am missing something here but can someone explain how I can get this to work

I have a method that takes a Func, I want to execute that func in the method a store the result in a local var.

internal List<MembershipUser> Users;

internal void FindType<T>(Func<List<MembershipUser>, T> finder)where T : List<MembershipUser>
{
     Users = x => finder(x);
}

This does not work. It says it cannot convert the Lambda as it is not a delegate type.

Any ideas?

A: 

You are trying to assign x => finder(x) (a lambda expression, e.g. anonymous delegate) to Users, a variable of type List<MembershipUser>. This is a type mismatch.

If you want to filter the existing Users list (this assumes that Users is already initialized and populated), then change your code to

Users = finder(Users);

If you are filtering some other list, then do something along the lines of

Users = finder(myUserList);

If finder is supposed to return a list without requiring any paramters, then change it from a Func<> to an Action<>

void FindType<T>(Action<T> finder) where T : List<MembershipUser>
{
    Users = finder();
}
Greg
+1  A: 

You're trying to assign an expression to a variable of type List<> (Users).

I suspect you realy want to do this:

Users = finder(Users)

Although that doesn't make a whole lot of sense on its own.

Daniel Renshaw
THis is the method I am trying to run:FindType<List<MembershipUsers>>(members =>{ return members.Where(member => member.IsApproved) .ToList<MembershipUser>();};
Dirk
Okay, and if you make the change I suggested, the result would be that Users is changed to be a list containing only the approved members. Is that what you want? Are you sure you don't really want FindType to return the results instead?
Daniel Renshaw
A: 

Without understanding exactly what you're doing, I can tell you that your syntax is off and you're not passing the correct number of parameters:

internal void FindType<T>(Func<List<MembershipUser>, T> finder, T x)
    where T : List<MembershipUser>
{
    Users = finder(T);
}

In this case, since you're limiting the type so strictly, the use of generics is quite superfluous. Removing them may make your code more understandable.

If you explain exactly what you want the method to do, we should be able to give you better guidance as how to fix the code.

Justin Niessner
A: 

Ok accepted about the wrong use of generics, thanks.

This is how I am trying to call it:

FindType>(members => { return members.Where(member => member.IsApproved) .ToList(); };

So I already have my lamda exprssion I just need Findtype to get the result and store it in the local variable.

Again I am probably missing the point but guidance greatly appreciated.

Dirk
A: 

I think you want to try to filter an arbitrary Enumerable of MembershipUser into a local List. Your filter should therefore be type Func<IEnumerable<MembershipUser>, List<MembershipUser>>. In addition one thing is missing: this list that you are trying to filter. This must be passed as a parameter to the filter when you call it. I assume it is passed as a parameter, but it could just as easily be another internal variable or property of your class.

This results in the following function (see below for full working sample):

void FindType(Func<IEnumerable<MembershipUser>, List<MembershipUser>> filter, IEnumerable<MembershipUser> list)
{
   Users = filter(list);
}

Something I learned from my functional programming courses in university: get your types correct first then the rest will follow. Think about what you are trying to do in terms of inputs and outputs. Not only for your functions, but also for your lambdas. (Which essentially are nameless functions).

Full working sample:

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Sample d = new Sample();
            IEnumerable<MembershipUser> ll = new List<MembershipUser>()
            {
                new MembershipUser() { Name ="1", IsApproved=false},
                new MembershipUser() { Name ="2", IsApproved=true},
            };

            d.FindType(members => members.Where(m => m.IsApproved).ToList(), ll);
            Console.WriteLine(d.Users.Count());
        }

        class MembershipUser
        {
            public string Name
            {get;set;}
            public bool IsApproved
            {get;set;}
        }

        class Sample
        {
            private List<MembershipUser> users;

            public void FindType(Func<IEnumerable<MembershipUser>, List<MembershipUser>> filter, IEnumerable<MembershipUser> list)
            {
                users = filter(list);
            }

            public List<MembershipUser> Users
            {
                get { return users; }
            }
        }
    }
}
Jeroen Huinink
Awesome, thankyou!
Dirk