相关疑难解决方法(0)

JavaScript闭包与匿名函数

我的一个朋友和我正在讨论什么是JS的封闭,什么不是.我们只是想确保我们真正理解它.

我们来看看这个例子吧.我们有一个计数循环,并希望在控制台上打印计数器变量延迟.因此,我们使用setTimeout闭包来捕获计数器变量的值,以确保它不会打印值N的N倍.

错误的解决方案,无需关闭或接近任何倒闭将是:

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}
Run Code Online (Sandbox Code Playgroud)

这当然会打印10次i循环后的值,即10.

所以他的尝试是:

for(var i = 0; i < 10; i++) {
    (function(){
        var i2 = i;
        setTimeout(function(){
            console.log(i2);
        }, 1000)
    })();
}
Run Code Online (Sandbox Code Playgroud)

按预期打印0到9.

我告诉他,他并没有使用封闭捕获i,但他坚持认为他是.我证明他没有使用闭包,将for循环体放在另一个setTimeout(将他的匿名函数传递给setTimeout),再次打印10次10​​.如果我将他的函数存储在a中var并在循环之后执行它同样适用,也打印10次10​​.所以我的论点是他并没有真正捕获它的值i,使他的版本不是一个闭包.

我的尝试是:

for(var i = 0; i < …
Run Code Online (Sandbox Code Playgroud)

javascript closures scope

551
推荐指数
10
解决办法
11万
查看次数

访问修改后的封闭(2)

这是Access到Modified Closure的问题扩展.我只是想验证以下内容是否足够安全,适合生产使用.

List<string> lists = new List<string>();
//Code to retrieve lists from DB    
foreach (string list in lists)
{
    Button btn = new Button();
    btn.Click += new EventHandler(delegate { MessageBox.Show(list); });
}
Run Code Online (Sandbox Code Playgroud)

我每次启动时都只运行一次.现在似乎工作正常.正如Jon在某些情况下提到的反直觉结果一样.那么我需要注意什么呢?如果列表不止一次运行会没问题吗?

.net c# resharper closures

101
推荐指数
1
解决办法
1万
查看次数

ReSharper警告 - 访问修改后的关闭

我有以下代码:

string acctStatus = account.AccountStatus.ToString();
if (!SettableStatuses().Any(status => status == acctStatus))
    acctStatus = ACCOUNTSTATUS.Pending.ToString();
Run Code Online (Sandbox Code Playgroud)

请注意,account.AccountStatus是ACCOUNTSTATUS类型的枚举.在第二行,ReSharper向我发出了acctStatus的"访问修改后的关闭"的警告.当我执行建议的操作,复制到本地变量时,它将代码修改为以下内容:

string acctStatus = realAccount.AccountStatus.ToString();
string s = acctStatus;
if (!SettableStatuses().Any(status => status == s))
    acctStatus = ACCOUNTSTATUS.Pending.ToString();
Run Code Online (Sandbox Code Playgroud)

为什么这比我原来的更好或更好?

编辑

它还建议在数组中包装局部变量,它产生:

string[] acctStatus = {realAccount.AccountStatus.ToString()};
if (!SettableStatuses().Any(status => status == acctStatus[0]))
    acctStatus[0] = ACCOUNTSTATUS.Pending.ToString();
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎很奇怪.

c# resharper warnings

37
推荐指数
1
解决办法
2万
查看次数

我该如何解决:在关闭resharper警告中访问foreach变量?

我收到了这个ReSharper警告:在关闭时访问foreach变量.使用不同版本的编译器编译时可能会有不同的行为.

这就是我正在做的事情:

@foreach(var item in Model)
{
    // Warning underlines "item".
    <div>@Html.DisplayBooleanFor(modelItem => item.BooleanField)</div>
}
Run Code Online (Sandbox Code Playgroud)

我的扩展如下:

public static MvcHtmlString DisplayBooleanFor<TModel, TValue>(
    this HtmlHelper<TModel> helper, 
    Expression<Func<TModel, TValue>> expression)
{
    bool value;

    try
    {
        var compiled = expression.Compile()(helper.ViewData.Model);
        value = Convert.ToBoolean(compiled);
    }
    catch (Exception)
    {
        value = false;
    }

    return MvcHtmlString.Create(value ? "Yes" : "No");
}
Run Code Online (Sandbox Code Playgroud)

请注意这是按预期工作但我如何避免此警告?
我将不胜感激任何帮助.

c# resharper

26
推荐指数
1
解决办法
1万
查看次数

C#lambda,当你想到的时候没有采用局部变量值?

鉴于:

void AFunction()
{

   foreach(AClass i in AClassCollection)
   {
      listOfLambdaFunctions.AddLast(  () =>  {  PrintLine(i.name); }  );
   }
}

void Main()
{
    AFunction();
    foreach( var i in listOfLambdaFunctions)
       i();
}
Run Code Online (Sandbox Code Playgroud)

现在你会认为这样做会对等:

void Main()
{

    foreach(AClass i in AClassCollection)
       PrintLine(i.name);
}
Run Code Online (Sandbox Code Playgroud)

但它没有,它将做的是每次打印AClassCollection中最后一项的名称!所以基本上每个lambda函数都使用相同的项目.我怀疑"当lambda被创建时"或"当它使用其中使用的外部变量的快照时"可能会有一些延迟,或者基本上只是持有'对局部变量的引用'i'

所以我这样做了:

string astr = "a string";
AFunc fnc = () => { System.Diagnostics.Debug.WriteLine(astr); };
astr = "changed";
fnc();
Run Code Online (Sandbox Code Playgroud)

而惊喜,惊喜,它输出"改变了!"

我正在使用XNA 3.1(无论是什么c#)

到底是怎么回事?lambda函数以某种方式存储变量或其他东西的"引用"吗?反正这个问题呢?

c# lambda

12
推荐指数
3
解决办法
9909
查看次数

c#在Lambda表达式中声明变量

下面的代码输出33而不是012.我不明白为什么在每次迭代中没有捕获新变量loopScopedi而不是捕获相同的变量.

Action[] actions = new Action[3];

for (int i = 0; i < 3; i++)
{

   actions [i] = () => {int loopScopedi = i; Console.Write (loopScopedi);};
}

foreach (Action a in actions) a();     // 333
Run Code Online (Sandbox Code Playgroud)

Hopwever,这段代码产生012.两者之间有什么区别?

Action[] actions = new Action[3];

for (int i = 0; i < 3; i++)
{
    int loopScopedi = i;
    actions [i] = () => Console.Write (loopScopedi);
}

foreach (Action a in actions) a();     // 012
Run Code Online (Sandbox Code Playgroud)

c# lambda

11
推荐指数
1
解决办法
1380
查看次数

有人能用简单的术语解释C#中的"访问修改后的闭包"吗?

可能重复:
什么是'关闭'?
访问修改后的闭包
访问修改后的闭包(2)

Resharper抱怨下面这段代码:

foreach (string data in _dataList)
    DoStuff (() => field);
Run Code Online (Sandbox Code Playgroud)

什么是关闭?我为什么要关心?

我已经读过关于数学和函数式编程的闭包,我在这里不知所措.我的大脑太沉重了.

简单来说,这里发生了什么?

c# closures

8
推荐指数
1
解决办法
6774
查看次数

当我使用线程将东西打印到控制台时,为什么会产生奇怪的结果呢?

我最近在阅读Rob Miles(这里)的非常好的pdf时进入了Threads .他在第160页(2012年,C#pdf)上有一个例子,但它没有写入控制台只是空循环.

我写了一个非常简单的线程生成循环,它创建了10个线程,在1000的每个倍数上将它们的ID写入屏幕.这很好 - 它向我展示了线程如何一起运行.我的问题从为什么我的输出如此困惑开始?通常当我运行下面的程序时,我会得到多个"Thread 3 Finished"行,我很确定,我应该只有一个.

我从MSDN 添加了一个"锁定"到循环但它似乎仍然产生奇数输出(我将在下面举一个例子).

    namespace ConsoleApplication1
    {
        class Program
        {
            static object sync = new object();

            static void Main(string[] args)
            {
                for (int i = 0; i < 10; i++)
                {
                    Thread myThread = new Thread(() => DoThis(i));
                    myThread.Start();
                }
                Console.ReadLine();
            }

            static void DoThis(int s)
            {
                lock (sync) // a new addition that hasn't helped
                {
                    for (long j = 0; j < 10000; j++)
                    {
                        if (j % …
Run Code Online (Sandbox Code Playgroud)

c# multithreading thread-safety

8
推荐指数
2
解决办法
1791
查看次数

C#访问修改后的闭包

public virtual void OnRegistrationJoin(RegistrationJoinEventArgs e)
{
    foreach (Mobile member in e.Team)
    {
        member.SendMessage(1161, "You join the {0}.", EventFullName);

        if (e.Team.Count > 1)
        {
            Joinees.Remove(member);
            member.SendMessage(1161, "Your team formation is:");

            int i = 0;

            foreach (Mobile parter in e.Team.Where(partner => partner != member).ToList())
            {
                member.SendMessage(1150, "{0}: {1}.", ++i, partner.Name);
            }
        }
    }

    Members.Add(e.Team);
}
Run Code Online (Sandbox Code Playgroud)

我通过resharper获得"访问修改后的闭包"警告,我想知道这段代码有什么问题,因为我在内循环中所做的只是发送消息?

c# resharper

7
推荐指数
1
解决办法
1231
查看次数

报告重复事件的预期事件序列的测试助手

我有一个帮助方法,用于我的单元测试,断言特定顺序的事件是按特定顺序引发的.代码如下:

public static void ExpectEventSequence(Queue<Action<EventHandler>> subscribeActions, Action triggerAction)
{
    var expectedSequence = new Queue<int>();
    for (int i = 0; i < subscribeActions.Count; i++)
    {
        expectedSequence.Enqueue(i);
    }

    ExpectEventSequence(subscribeActions, triggerAction, expectedSequence);
}

    public static void ExpectEventSequence(Queue<Action<EventHandler>> subscribeActions, Action triggerAction, Queue<int> expectedSequence)
    {
        var fired = new Queue<int>();
        var actionsCount = subscribeActions.Count;

        for(var i =0; i< actionsCount;i++)
        {
            subscription((o, e) =>
                {
                    fired.Enqueue(i);
                });
        }

        triggerAction();

        var executionIndex = 0;

        var inOrder = true;

        foreach (var firedIndex in fired)
        {

            if (firedIndex != …
Run Code Online (Sandbox Code Playgroud)

c# events lambda unit-testing anonymous-function

7
推荐指数
1
解决办法
241
查看次数