Как вызвать Func для установки локального списка‹›

Я думаю, что я что-то упускаю здесь, но может кто-нибудь объяснить, как я могу заставить это работать

У меня есть метод, который принимает Func, я хочу выполнить эту функцию в методе, чтобы сохранить результат в локальной переменной.

internal List<MembershipUser> Users;

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

Это не работает. Он говорит, что не может преобразовать Lambda, поскольку это не тип делегата.

Любые идеи?


Хорошо, принято о неправильном использовании дженериков, спасибо.

Вот как я пытаюсь это назвать:

FindType<List<MembershipUsers>>(
    members => 
    { 
        return members.Where(member => member.IsApproved).ToList<MembershipUser>(); 
    };

Итак, у меня уже есть лямбда-выражение. Мне просто нужен Findtype, чтобы получить результат и сохранить его в локальной переменной.

Опять же, я, вероятно, упускаю суть, но очень ценю руководство.


person Dirk    schedule 16.08.2010    source источник
comment
Как бы то ни было, бессмысленно делать этот метод универсальным. Это эквивалентно FindType (Func‹List‹MembershipUser›, List‹MembershipUser›› finder)   -  person Alex Humphrey    schedule 16.08.2010


Ответы (4)


Я думаю, вы хотите попытаться отфильтровать произвольное перечисление MembershipUser в локальный список. Поэтому ваш фильтр должен быть типа Func<IEnumerable<MembershipUser>, List<MembershipUser>>. Кроме того, отсутствует одна вещь: этот список, который вы пытаетесь отфильтровать. Это должно быть передано в качестве параметра фильтру при его вызове. Я предполагаю, что он передается как параметр, но с таким же успехом это может быть другая внутренняя переменная или свойство вашего класса.

В результате получается следующая функция (полный рабочий пример см. ниже):

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

Кое-что, чему я научился на своих курсах функционального программирования в университете: сначала правильно определите свои типы, а затем приложится все остальное. Подумайте о том, что вы пытаетесь сделать с точки зрения входов и выходов. Не только для ваших функций, но и для ваших лямбд. (которые по сути являются безымянными функциями).

Полный рабочий образец:

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; }
            }
        }
    }
}
person Jeroen Huinink    schedule 16.08.2010

Вы пытаетесь присвоить выражение переменной типа List‹> (Users).

Я подозреваю, что вы действительно хотите сделать это:

Users = finder(Users)

Хотя само по себе это не имеет особого смысла.

person Daniel Renshaw    schedule 16.08.2010
comment
Это метод, который я пытаюсь запустить: FindType‹List‹MembershipUsers››(members =› { returnmembers.Where(member =›member.IsApproved) .ToList‹MembershipUser›(); }; - person Dirk; 16.08.2010
comment
Хорошо, и если вы внесете изменение, которое я предложил, результатом будет то, что Пользователи будут изменены, чтобы быть списком, содержащим только утвержденных участников. Это то, что вы хотите? Вы уверены, что на самом деле не хотите, чтобы FindType вместо этого возвращал результаты? - person Daniel Renshaw; 16.08.2010

Не понимая точно, что вы делаете, я могу сказать вам, что ваш синтаксис отключен, и вы не передаете правильное количество параметров:

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

В этом случае, поскольку вы так строго ограничиваете тип, использование дженериков совершенно излишне. Их удаление может сделать ваш код более понятным.

Если вы объясните, что именно вы хотите, чтобы этот метод делал, мы сможем дать вам лучшее руководство по исправлению кода.

person Justin Niessner    schedule 16.08.2010

Вы пытаетесь присвоить x => finder(x) (лямбда-выражение, например анонимный делегат) Users, переменной типа List<MembershipUser>. Это несоответствие типов.

Если вы хотите отфильтровать существующий список пользователей (это предполагает, что Users уже инициализирован и заполнен), измените свой код на

Users = finder(Users);

Если вы фильтруете какой-то другой список, сделайте что-нибудь вроде

Users = finder(myUserList);

Если предполагается, что finder возвращает список без каких-либо параметров, измените его с Func<> на Action<>.

void FindType<T>(Action<T> finder) where T : List<MembershipUser>
{
    Users = finder();
}
person Greg    schedule 16.08.2010