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 开发者_JS百科delegate type.
Any ideas?
Ok accepted about the wrong use of generics, thanks.
This is how I am trying to call it:
FindType<List<MembershipUsers>>(
members =>
{
return members.Where(member => member.IsApproved).ToList<MembershipUser>();
};
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.
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.
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; }
}
}
}
}
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.
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();
}
精彩评论