为什么从投影创建的整数变量不能递增?
Why can an integer variable created from projection not be incremented?
我已经 运行 进入了 C# 的一个我没想到的小众行为。幸运的是我的单元测试发现了意想不到的行为,但我很惊讶并且我不明白为什么它会这样。我用以下代码重现了这个问题。
static void Main(string[] args)
{
var initialCollection = new bool[] { false, true };
var projectedCollection = initialCollection.Select(o => (initialObj: o, Counter: 0)).ToArray();
for (int i = 0; i < 10; i++)
{
var objectFromProjection = projectedCollection.First(o => o.initialObj == (i % 2 == 0));
Console.WriteLine($"For initial obj {objectFromProjection.initialObj}, counter is now {++objectFromProjection.Counter}");
}
Console.ReadKey();
}
因为我在投影后添加了 ToArray
,所以我希望计数器变量不会每次都重新初始化为零。但是,对于循环 for
.
的每次迭代,它都会重新初始化为 0
这是输出:
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 1
For initial obj False, counter is now 1
这是我认为它会做的事情:
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 2
For initial obj False, counter is now 2
For initial obj True, counter is now 3
For initial obj False, counter is now 3
For initial obj True, counter is now 4
For initial obj False, counter is now 4
For initial obj True, counter is now 5
For initial obj False, counter is now 5
为什么计数器会重置为零而不是保持增量值?
因为你正在处理一个值元组。观察:
for (int i = 0; i < 10; i++)
{
var objectFromProjection = projectedCollection.First(o => o.initialObj == (i % 2 == 0));
//Always false
Console.WriteLine(ReferenceEquals(projectedCollection[0], objectFromProjection));
Console.WriteLine(ReferenceEquals(projectedCollection[1], objectFromProjection));
}
var objectFromProjection = projectedCollection.First(o => o.initialObj == (i % 2 == 0));
Console.WriteLine($"For initial obj {objectFromProjection.initialObj},
counter is now {++objectFromProjection.Counter}");
每次循环运行都有意义 objectFromProjection
ValueTuple 正在创建,它的值将始终为 1,因为 objectFromProjection
将始终具有 1 个元素,因为 .First()
returns 总是一个元素..
我想这会为您澄清一些事情。
var initialCollection = new bool[] { false, true };
var projectedCollection = initialCollection.Select(o => (initialObj: o, Counter: 0)).ToArray();
(bool initialObj, int Counter) d = new ValueTuple<bool,int>();
for (int i = 0; i < 10; i++)
{
d = projectedCollection.First(o => o.initialObj == (i % 2 == 0));
Console.WriteLine($"For initial obj {d.initialObj}, counter is now {++d.Counter}");
}
我已经 运行 进入了 C# 的一个我没想到的小众行为。幸运的是我的单元测试发现了意想不到的行为,但我很惊讶并且我不明白为什么它会这样。我用以下代码重现了这个问题。
static void Main(string[] args)
{
var initialCollection = new bool[] { false, true };
var projectedCollection = initialCollection.Select(o => (initialObj: o, Counter: 0)).ToArray();
for (int i = 0; i < 10; i++)
{
var objectFromProjection = projectedCollection.First(o => o.initialObj == (i % 2 == 0));
Console.WriteLine($"For initial obj {objectFromProjection.initialObj}, counter is now {++objectFromProjection.Counter}");
}
Console.ReadKey();
}
因为我在投影后添加了 ToArray
,所以我希望计数器变量不会每次都重新初始化为零。但是,对于循环 for
.
这是输出:
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 1
For initial obj False, counter is now 1
这是我认为它会做的事情:
For initial obj True, counter is now 1
For initial obj False, counter is now 1
For initial obj True, counter is now 2
For initial obj False, counter is now 2
For initial obj True, counter is now 3
For initial obj False, counter is now 3
For initial obj True, counter is now 4
For initial obj False, counter is now 4
For initial obj True, counter is now 5
For initial obj False, counter is now 5
为什么计数器会重置为零而不是保持增量值?
因为你正在处理一个值元组。观察:
for (int i = 0; i < 10; i++)
{
var objectFromProjection = projectedCollection.First(o => o.initialObj == (i % 2 == 0));
//Always false
Console.WriteLine(ReferenceEquals(projectedCollection[0], objectFromProjection));
Console.WriteLine(ReferenceEquals(projectedCollection[1], objectFromProjection));
}
var objectFromProjection = projectedCollection.First(o => o.initialObj == (i % 2 == 0));
Console.WriteLine($"For initial obj {objectFromProjection.initialObj},
counter is now {++objectFromProjection.Counter}");
每次循环运行都有意义 objectFromProjection
ValueTuple 正在创建,它的值将始终为 1,因为 objectFromProjection
将始终具有 1 个元素,因为 .First()
returns 总是一个元素..
我想这会为您澄清一些事情。
var initialCollection = new bool[] { false, true };
var projectedCollection = initialCollection.Select(o => (initialObj: o, Counter: 0)).ToArray();
(bool initialObj, int Counter) d = new ValueTuple<bool,int>();
for (int i = 0; i < 10; i++)
{
d = projectedCollection.First(o => o.initialObj == (i % 2 == 0));
Console.WriteLine($"For initial obj {d.initialObj}, counter is now {++d.Counter}");
}