为什么对外部数据源的更改不会反映,而对内部数据源的更改会显示

本文关键字:数据源 内部 显示 对外部 为什么 | 更新日期: 2023-09-27 18:31:17

为什么对外部数据源的更改没有反映,而对内部数据源的更改却显示出来?请帮忙

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() 时,我得到了预期的结果,那么是因为该选择是懒惰的吗?请解释一下。

更新

我尝试的是 - 在 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);

为什么对外部数据源的更改不会反映,而对内部数据源的更改会显示

我认为

,问题是第一个变量(inputDS1)不包含在任何匿名函数(lambda)中,那么编译器不会为其生成闭包。

编译器将查询转换为如下所示的内容:

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

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

你得到的是来自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();激活方法时, 因此不会因之后调用的命令而出现任何意外行为。

据我所知,部分

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

围绕输入参数交换,而不是从 LINQ 语句获得的结果。