What Func<;int,int>;表现得像这样
本文关键字:int 像这样 gt Func What lt | 更新日期: 2023-09-27 17:58:01
样品1:
static void DelegateTest()
{
Func<int, int> test = null;
for(int i=0;i<2;i++)
{
int y = i;
test = (t) => y;
}
Console.WriteLine(test(1)); // This thing prints 1
//Console.ReadLine();
}
样品2:
static void DelegateTest2()
{
Func<int, int> test = null;
for (int i = 0; i < 2; i++)
{
test = (t) => i;
}
// This thing prints 2. I want to know why?
//Because 'i' gets out of scope when test(1) gets called and it should print 1
Console.WriteLine(test(1));
Console.ReadLine();
我想知道为什么当我们在范围外调用Func时,它会得到I的增量值?
因为对于两个循环,i
的最后一个值都是2
。在第一个步骤中,不执行最后一步,因为循环条件评估为false,因为i
变为2。这就是为什么y
从未分配给2
。在第二个片段中,lambda捕获i
的最后一个值,即2
,这就是它打印2的原因。
您正在将1
传递给您的方法,但这并不重要。即使你传递了一个不同的值,你仍然会得到相同的结果。这一切都是关于闭包的。
如果你仍然有疑问,并且你想确定y
和i
的最后一个值是什么,你可以做另一个简单的测试:
int y = 0;
for (int k = 0; k < 2; k++)
{
y = k;
}
Console.WriteLine(y); // writes 1
int i = 0;
for(; i < 2; i++) { }
Console.WriteLine(i); // writes 2
在第二个样本中(实际上,在两个样本中),您创建了一个名为Closure的东西。每当您将变量用作lambda语句的一部分或在该lambda/委托之外定义的匿名委托时,都会创建闭包。此闭包捕获(关闭)for
循环中的i
变量,防止其"超出范围"。在脱离循环的条件失败之前,for
循环必须最后一次递增i
变量,使其变为2
,因此最终使用2
而不是1
。
第一个示例对y
变量执行相同的操作。您仍然可以捕获/关闭变量并防止它超出范围。但是,y
变量从未设置为2
。该示例中的i
变量仍然递增为2
,但在此之后,代码不会进入循环,因此y
永远不会设置为2
,这样您仍然可以看到1
的预期结果。
在这两种情况下,传递给该方法的1
值都不会被使用,也没有任何效果。