代码之家  ›  专栏  ›  技术社区  ›  Andres

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

  •  0
  • Andres  · 技术社区  · 15 年前

    好吧,我认为这个问题的标题还远未明确,但我希望下面的文字可以澄清它。

        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 回复  |  直到 15 年前
        1
  •  1
  •   Lasse V. Karlsen    15 年前

    很遗憾,列表引用对代码不可用,因为它只作为调用链期间使用的临时表达式结果的一部分存在于堆栈中。

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

    在本例中,我将执行以下操作:

    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
  •  2
  •   Vlad    15 年前
    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);
    
        3
  •  0
  •   VladV    15 年前
    List<int> nums = Load();
    List<int> even = nums.FindAll(delegate(int x)
            {
                count = nums.Count;
                return (x % 2) == 0;
            });
    

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