如何访问委托内的列表成员

时间:2010-11-10 13:15:33

标签: c# delegates

我认为这个问题的标题很明显,但我希望下面的文字可以清楚地说明。

下面的代码只是一个概念,但说明了我正在尝试做的事情。如何访问方法返回的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;
    }

这是原始代码 - 只是为了说明为什么我不想创建新的List,因为它只是一个临时列表而没有任何其他用途。

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 个答案:

答案 0 :(得分:2)

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 :(得分:1)

不幸的是,列表引用不适用于您的代码,因为它只作为调用链中使用的临时表达式结果的一部分存在于堆栈中。

因此,您唯一的选择是在使用它之前将其显式存储到变量中。

在这个例子中,我会这样做:

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;
});

并重写为lambda:

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

答案 2 :(得分:0)

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

否则,您需要的对象不在委托范围内。