为什么对外部数据源的更改没有反映出来,而它们是为内部数据源显示的?

时间:2013-09-15 08:00:35

标签: c# linq

为什么不反映外部数据源的更改,而它们显示内部数据源?请帮忙

public static void MyMethod(char[] inputDS1, char[] inputDS2)
{
    Console.WriteLine("\n'from' clause - Display all possible combinations of a-b-c-d.");

    //query syntax
    IEnumerable<ChrPair> resultset = from res1 in inputDS1
                                     from res2 in inputDS2
                                     select new ChrPair(res1, res2);

    //Write result-set
    Console.WriteLine("\n\nOutput list -->");
    displayList(resultset);

    //swap positions
    //obs: changes to the first ds is not reflected in the resultset.
    char[] temp = inputDS1;
    inputDS1 = inputDS2;
    inputDS2 = temp;

    //run query again
    displayList(resultset);
    Console.WriteLine("\n------------------------------------------");
}

输入:

('a','b'), ('c','d')

输出:

ac, ad, bc, bd, **aa. ab, ba, bb**

我预计所有可能的组合(ac,ad,bc,bd, ca,cb,da,db ),因为我在第二次写入之前交换了数据源。当我在第二次写入之前执行ToList()时,我得到了预期的结果,所以是因为Select是懒惰的吗?请解释一下。

更新

我尝试的是 - 在ds-swap之后向查询表达式添加ToList()(强制立即执行)。我得到了正确的结果 - ac,ad,bc,bd,ca,cb,da,db。 这将返回预期的结果。

//query syntax
IEnumerable<ChrPair> resultset = from res1 in inputDS1
                                from res2 in inputDS2
                                select new ChrPair(res1, res2);

//Write result-set
Console.WriteLine("\n\nOutput list -->");
displayList(resultset);

//swap positions
//obs: changes to the first ds is not reflected in the resultset.
char[] temp = inputDS1;
inputDS1 = inputDS2;
inputDS2 = temp;

resultset = (from res1 in inputDS1
            from res2 in inputDS2
            select new ChrPair(res1, res2)).ToList();

//run query again
displayList(resultset);

3 个答案:

答案 0 :(得分:1)

你得到的是来自inputDS1的字符与来自inputDS2的字符的组合。这就是查询

    IEnumerable<ChrPair> resultset = from res1 in inputDS1
                                     from res2 in inputDS2
                                     select new ChrPair(res1, res2);

确实如此,这就是您从中提出的问题:“从inputDS1中获取1个项目,从inputDS2中获取1个项目并将这两个项目合并为new ChrPair

修改

在理解了你的问题之后,让我解释一些非常基本的东西:

    IEnumerable<ChrPair> resultset = from res1 in inputDS1
                                     from res2 in inputDS2
                                     select new ChrPair(res1, res2);

不会返回列表或IEnumerable<ChrPair>。它返回一个具有源(inputDS1)和输入的方法。当你交换这两个时,你搞乱了方法的输入,但源没有改变(它可能被复制而不仅仅是被引用)。当你执行.ToList();时激活方法,因此之后调用的命令不会产生任何意外行为。

答案 1 :(得分:1)

我认为,问题是第一个变量(inputDS1)不包含在任何匿名函数(lambda)中,然后编译器就不会为它生成闭包。

编译器将查询转换为以下内容:

IEnumerable<ChrPair> resultset = 
    inputDS1.SelectMany(c => inputDS2.Select(c1 => new ChrPair(c, c1)));

如您所见,inputDS1不包含在任何匿名(lambda)中。相反,inputDS2包含在lambda中然后编译器将为它生成闭包。因此,在第二次执行查询时,您可以访问已修改的闭包inputDS2

答案 2 :(得分:-1)

从我所看到的,部分

char[] temp = inputDS1;
    inputDS1 = inputDS2;
    inputDS2 = temp;

交换输入参数,而不是你从linq语句得到的结果。