Как получить доступ к члену списка внутри делегата - PullRequest
0 голосов
/ 10 ноября 2010

Ну, я думаю, что название этого вопроса далеко не ясно, но я надеюсь, что текст ниже может прояснить это.

Код ниже является только концепцией, но иллюстрирует то, что я пытаюсь сделать. Как я могу получить доступ к члену List (внутри делегата), возвращенному методом, без назначения его локальной переменной List? Это возможно?

    static void ListTest()
    {
        int count = 0;

        List<int> even = Load().FindAll(delegate(int x)
        {
            count = Count; //<------- How can I get the Count from the List returned by the Load method?
            return (x % 2) == 0;
        });

        System.Console.WriteLine("Count = {0} and there are {1} even numbers", count, even.Count);
    }

    static List<int> Load()
    {
        List<int> array = new List<int>();
        int[] vet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        array.AddRange(vet);

        return array;
    }

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

private List<MailItem> Find<T_Item, T_Adaptor>(T_Adaptor adaptor, MailItemId MailId)
{
    List<T_Item> Items = ((List<T_Item>)(typeof(T_Adaptor).InvokeMember(
            "Load",
            BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
            null, adaptor,
            new Object[] { null, MailId, null }))).FindAll(
                delegate(T_Item itm)
                {
                    MailItem mi = itm as MailItem;
                    if (mi == null) return false;
                    return (mi.StateInd.Code == StateInd.ASSIGNED); 
                });

    List<MailItem> mailItems = new List<MailItem>();
    foreach (T_Item itm in Items)
        mailItems.Add(itm as MailItem);

    return mailItems;
}

Спасибо

Ответы [ 3 ]

2 голосов
/ 10 ноября 2010
var load = Load();
List<int> even = load.FindAll(delegate(int x)
{
    count = load.Count;
    return (x % 2) == 0;
});

Редактировать:
Еще одна идея о том, как достичь желаемого результата, используя методы расширения в качестве синтаксического сахара:

static public class ListExt
{
    static public List<T> StoreSize<T>(this List<T> self, out int size)
    {
        size = (self != null) ? self.Count : -1;
        return self;
    }
}
...
List<int> even = Load().StoreSize(out count).FindAll(x => (x % 2) == 0);
1 голос
/ 10 ноября 2010

К сожалению, ссылка на список недоступна для вашего кода, поскольку она живет в стеке только как часть результатов временных выражений, используемых в цепочке вызовов.

Таким образом, ваш единственный вариант - явно сохранить его в переменной перед использованием.

В этом примере я бы сделал это:

var list = Load();
List<int> even = list.FindAll(delegate(int x)
{
    count = list.Count;
    return (x % 2) == 0;
});

Конечно, теперь вы можете просто сделать:

var list = Load();
int count = list.Count;
List<int> even = list.FindAll(delegate(int x)
{
    return (x % 2) == 0;
});

А также переписать в лямбду:

var list = Load();
int count = list.Count;
List<int> even = list.FindAll(x => (x % 2) == 0);
0 голосов
/ 10 ноября 2010
List<int> nums = Load();
List<int> even = nums.FindAll(delegate(int x)
        {
            count = nums.Count;
            return (x % 2) == 0;
        });

В противном случае нужный вам объект не попадает в сферу действия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...