虽然var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res) {
res.sendfile('index.html');
});
http.listen(3000, function() {
console.log('listening on *:3000');
});
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconected');
});
socket.on('chat-message', function (message) {
console.log('message: ' + message.text);
});
});
循环中的迭代器变量是不可变的,但如果我使用foreach
进行修改,我可以在下面的示例中修改我的集合:
Where()
输出:
static void Main(string[] args)
{
var list = new List<int> { 1, 2, 3, 4 };
foreach (var listElement in list)
{
Console.WriteLine(listElement + " ");
list = list.Where(x => x != listElement).ToList();
}
Console.WriteLine("Count: " + list.Count);
}
有人可以解释一下这种行为吗?
答案 0 :(得分:2)
我相信在foreach (var listElement in list)
中,您将获得该list
的{{1}}引用的枚举器。
在循环中,为list
变量分配一个新实例,但循环使用的枚举器保留对原始枚举器的引用。
你不能做的是改变原始实例。即执行list.Remove(listElement)
,因为这会改变您尝试枚举的实际数据
如果将代码扩展到foreach循环实际执行的操作
,这可能会有所帮助static void Main(string[] args)
{
var list = new List<int> { 1, 2, 3, 4 };
var enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
var listElement = enumerator.Current;
Console.WriteLine(listElement + " ");
list = list.Where(x => x != listElement).ToList();
}
enumerator.Dispose();
Console.WriteLine("Count: " + list.Count);
}
答案 1 :(得分:2)
显示的代码从不&#34;修改集合&#34;这个短语的共同含义(添加/删除现有集合中的元素),而不是创建新集合。结果,没有&#34;集合被修改&#34;您可能期望的异常。
答案 2 :(得分:0)
实际上,由于您没有添加/删除集合中的任何项目,因此未对集合进行修改。关于list
变量的引用,我同意Lee,即循环保留对原始枚举器的引用。
答案 3 :(得分:0)