我是LINQ的新手,我遇到嵌套的问题:
using System;
using System.Linq;
class MultipleFroms
{
static void Main()
{
char[] chrs = { 'A', 'B', 'C'};
char[] chrs2 = { 'X', 'Y', 'Z' };
var pairs = from ch1 in chrs
from ch2 in chrs2
select ch1+" "+ ch2;
Console.WriteLine("For ABC and XYZ: ");
foreach (var p in pairs)
Console.WriteLine(p);
Console.WriteLine();
Console.WriteLine("For D and W: ");
chrs = new char[] { 'D' };
chrs2 = new char[] { 'W' };
foreach (var p in pairs)
Console.WriteLine(p);
}
}
Run Code Online (Sandbox Code Playgroud)
在输出中我有:
For ABC and XYZ:
A X
A Y
A Z
B X
B Y
B Z
C X
C Y
C Z
For D and W:
A W
B W
C W
Run Code Online (Sandbox Code Playgroud)
但我预计:
...
For D and W:
D W
Run Code Online (Sandbox Code Playgroud)
为什么pairs在第二种情况下使用"旧" chrs,{ 'A', 'B', 'C'}而不是{'D'}?
Min*_*s97 13
这个问题有几个很好的答案,说明显而易见的 - 你需要重新分配你的pairs变量.但是,我对这种奇怪的行为更感兴趣 - 因为,为什么重新分配chrs2会对枚举的结果产生影响,而重新分配chrs则不会.
如果我们使用嵌套from-s,看起来像重新分配任何已使用的集合(FIRST除外)会影响枚举的结果:http://ideone.com/X7f3eQ.
现在,正如您应该知道的那样,LINQ"查询语法"只是用于链接来自System.Linq库的扩展方法调用的语法糖.让我们来看看你的具体例子:
var pairs = from ch1 in chrs
from ch2 in chrs2
select ch1 + " "+ ch2;
Run Code Online (Sandbox Code Playgroud)
变
var pairs = chrs.SelectMany(ch1 => chrs2, (ch1, ch2) => ch1 + " " + ch2);
Run Code Online (Sandbox Code Playgroud)
(或者,使用非扩展方法语法SelectMany(chrs, ch1 => chrs2, (ch1, ch2) => ch1 + " " + ch2))
(请在此处查看:http://ideone.com/NjVeLD)
发生什么了?SelectMany将chrs两个lambda作为参数,并生成一个IEnumerable,然后可以枚举它们以开始实际评估.
现在,每当我们重新分配时chrs2,它都会在lambda中发生变化,因为它是一个捕获的变量.但是,这显然不适用chrs!
您必须将查询视为方法调用,其中该方法接收第一个数据源 ( chrs) 作为参数。问题是您无法在设置后重新分配已调用该方法的对象。第二个数据源(chrs2)就像一个全局变量,这样当你更新它的值时,查询的结果也会改变。
更好的方法是将查询转移到方法中:
public static IEnumerable<string> Pairs(char[] chrs,char[] chrs2)
{
return from ch1 in chrs
from ch2 in chrs2
select ch1+" "+ ch2;
}
Run Code Online (Sandbox Code Playgroud)
这样你就可以做这样的事情:
static void Main(string[] args)
{
char[] chrs = { 'A', 'B', 'C' };
char[] chrs2 = { 'X', 'Y', 'Z' };
Console.WriteLine("For ABC and XYZ: ");
foreach (var p in Pairs(chrs,chrs2))
Console.WriteLine(p);
Console.WriteLine();
Console.WriteLine("For D and W: ");
chrs = new char[] { 'D' };
chrs2 = new char[] { 'W' };
foreach (var p in Pairs(chrs, chrs2))
Console.WriteLine(p);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
494 次 |
| 最近记录: |