相关疑难解决方法(0)

C#中循环中的捕获变量

我遇到了一个关于C#的有趣问题.我有如下代码.

List<Func<int>> actions = new List<Func<int>>();

int variable = 0;
while (variable < 5)
{
    actions.Add(() => variable * 2);
    ++ variable;
}

foreach (var act in actions)
{
    Console.WriteLine(act.Invoke());
}
Run Code Online (Sandbox Code Playgroud)

我希望它输出0,2,4,6,8.但是,它实际输出5个10.

似乎是由于所有操作都涉及一个捕获的变量.结果,当它们被调用时,它们都具有相同的输出.

有没有办法解决这个限制,让每个动作实例都有自己的捕获变量?

c# closures captured-variable

202
推荐指数
7
解决办法
5万
查看次数

以编程方式构建LINQ查询而没有局部变量欺骗我

假设我的对象处于完美的工作状态(即TDD让我觉得它们有效).

我有一个我这样创建的列表(正确缩进除外):

var result = from v in vendors
             from p in v.Products
             orderby p.Name
             select p;
Run Code Online (Sandbox Code Playgroud)

这有效 - 我从所有供应商处获得所有产品.

现在我有一个条件列表,由用户在运行时构建.让我们应用它们:

foreach (Attribute a in requiredAttributes)
{
    result = result.Where(p => p.Attributes.Contains(a));
}
Run Code Online (Sandbox Code Playgroud)

这可能是原始的,但我认为它有用.但是,在完成此foreach循环之后,当您枚举"result"时,它将包含其Attributes属性(也是集合)中具有requiredAttributes集合的LAST属性的所有产品.

对我来说,这种气味就像"a"被覆盖在某个地方,每次旅行通过循环,只有最后一个适用.

如果没有以某种方式将扩展方法写入IEnumerable,称为ContainsAll(IEnumerable)或其他类似的东西,我怎么能实现我想要的,这基本上是一个逻辑AND,只给我那些具有所有必需属性的产品?

c# linq

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

JavaScript中的奇怪内容"for"

我正在使用jQuery,我有一个我不明白的奇怪的事情.我有一些代码:

for (i = 1; i <= some_number; i++) {
    $("#some_button" + i).click(function() {
        alert(i);
    });
}
Run Code Online (Sandbox Code Playgroud)

正如名字所说的"#some_button" - 它们是一些按钮.点击它们时,应该弹出一个带有它号码的方框,对吗?但他们没有.如果有4个按钮,它们总是弹出"5"(按钮计数+ 1).为什么会这样?

javascript jquery closures loops for-loop

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

for循环中事件处理程序的匿名方法

这可以在for循环中完成吗?

        TickEventArgs targs1 = new TickEventArgs(lbl1_up_time, _elapsedTime_up1);
        timer_up1.Tick += (sender, e) => Tick(targs1);

        TickEventArgs targs2 = new TickEventArgs(lbl2_up_time, _elapsedTime_up2);
        timer_up2.Tick += (sender, e) => Tick(targs2);

        TickEventArgs targs3 = new TickEventArgs(lbl3_up_time, _elapsedTime_up3);
        timer_up3.Tick += (sender, e) => Tick(targs3);

        TickEventArgs targs4 = new TickEventArgs(lbl4_up_time, _elapsedTime_up4);
        timer_up4.Tick += (sender, e) => Tick(targs4);

        TickEventArgs targs5 = new TickEventArgs(lbl5_up_time, _elapsedTime_up5);
        timer_up5.Tick += (sender, e) => Tick(targs5);
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为我超出界限(5)

        targs[0] = new TickEventArgs(lbl1_up_time, _elapsedTime_up1);
        targs[1] = new TickEventArgs(lbl2_up_time, _elapsedTime_up2);
        targs[2] = new TickEventArgs(lbl3_up_time, _elapsedTime_up3);
        targs[3] = new …
Run Code Online (Sandbox Code Playgroud)

c# event-handling winforms

7
推荐指数
2
解决办法
1761
查看次数

向Linq 2 Sql查询动态添加未确定数量的子句的正确方法是什么?

此函数用于返回用户搜索输入的联系人列表.搜索词的数量始终至少为一,但可能很多.

public IList<Contact> GetContacts(string[] searchTerms)
{
    using (dbDataContext db = new dbDataContext())
    {
        var contacts = from _contacts in db.Contacts
                       orderby _contacts.LastName ascending, _contacts.FirstName ascending
                       select _contacts;

        foreach (string term in searchTerms)
        {
            contacts = (IOrderedQueryable<Contact>)contacts.Where(x => SqlMethods.Like(x.FirstName, "%" + term + "%")
                                                                    || SqlMethods.Like(x.MiddleName, "%" + term + "%")
                                                                    || SqlMethods.Like(x.LastName, "%" + term + "%")
                                                                    || SqlMethods.Like(x.PreferredName, "%" + term + "%"));
        }

        return contacts.ToList<Contact>();
    }
}
Run Code Online (Sandbox Code Playgroud)

问题出在循环中.即使生成的sql看起来是正确的,也只使用了最后一个搜索词(就像为术语数生成了正确数量的子句一样).

示例 - 如果我传递两个术语('andr','sm'),生成的sql显示两个子句块,但只使用'sm'作为两个块中的param.

我究竟做错了什么?我应该使用SqlMethods吗?

.net c# linq-to-sql

5
推荐指数
1
解决办法
64
查看次数

如何抑制VB的"迭代变量不应该在lambda表达式中使用"

我在VB.NET中使用LINQ,有时我会遇到类似的查询

For i = 0 To 10
  Dim num = (From n In numbers Where n Mod i = 0 Select n).First()
Next
Run Code Online (Sandbox Code Playgroud)

然后它会出现警告" 在lambda表达式中使用迭代变量可能会产生意外结果.相反,在循环中创建一个局部变量并为其赋值迭代变量的值."

我知道在lambda表达式中使用迭代变量不是一个好习惯,因为只在需要时才计算lambda表达式.(这个问题是关于那个)

现在我的问题是,如何在使用First(),Single(),ToList()等结构对就地计算表达式的情况下抑制此警告(这只是一个警告,但我喜欢我的代码清理.)

(声明一个局部变量并将迭代变量传递给它是一个选项,但我正在寻找一个干净的解决方案.)

vb.net iteration lambda suppress-warnings

5
推荐指数
1
解决办法
1802
查看次数

Rx Task.Factory.StartNew在.Net 3.5问题上启动两个任务

我正在使用.Net 3.5上的Reactive Extensions库的任务部分

它大部分工作顺利,但在一个地方它调用相同的任务两次.

电话看起来像这样:

Task.Factory.StartNew(
    () => Processor.ProcessMessage(incomingMessage),
    TaskCreationOptions.PreferFairness );
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?这是一个错误吗?

----更新

我认为问题在于c#在lambdas中关闭的方式.问题不在TPL中,与普通旧线程池一起返回同样的问题.

这解决了它:

foreach (var Processor in processors)
{
 object[] crap = new object[2];
 crap[0] = Processor;
 crap[1] = incomingMessage;
 Task.Factory.StartNew(Magic, crap, TaskCreationOptions.PreferFairness);
}

public void Magic(object obj)
{
 object[] crap =(object[]) obj;
 ((IIncomingMessageProcessor)crap[0]).ProcessMessage((IncomingMessageBase)crap[1]);
}
Run Code Online (Sandbox Code Playgroud)

原始来源是:

foreach (var Processor in processors)
{
Task.Factory.StartNew(
    () => Processor.ProcessMessage(incomingMessage),
    TaskCreationOptions.PreferFairness );
}
Run Code Online (Sandbox Code Playgroud)

所以我在处理器周围关闭,我想问题是它为lambda回收相同的对象并交换处理器.

----更新2

我确信这是问题所在.我在创建任务时重构和调试了System.Threading.dll,它是使用相同的委托(Same ObjectID)创建的,并且处理器在迭代之间的Target属性中发生了变化.谁知道一个好的工作?

----更新3这也有效(感谢Judah Himango):

foreach (var processor in processors)
{
 var crap = processor;
 Task.Factory.StartNew(() => crap.ProcessMessage(incomingMessage), …
Run Code Online (Sandbox Code Playgroud)

.net c# multithreading system.reactive

4
推荐指数
1
解决办法
2128
查看次数

为什么我会得到:"lambda表达式中的迭代变量可能会产生意外结果"

可能重复:
为什么在lambda表达式中使用迭代变量是不好的

为什么我会得到:"lambda表达式中的迭代变量可能会产生意外结果"?假设我有以下代码:

  Dim writeAbleColumns As String() = {"IsSelected", "IsFeeExpense", "IsSubscriptionRedemption"}
  With grid
     For Each column As DataGridViewColumn In .Columns
      column.ReadOnly = Not Array.Exists(writeAbleColumns, Function(arrElement) column.Name = arrElement)
      Next
  End With
Run Code Online (Sandbox Code Playgroud)

我收到警告:

Warning 1   Using the iteration variable in a lambda expression may have unexpected results.  Instead, create a local variable within the loop and assign it the value of the iteration variable.
Run Code Online (Sandbox Code Playgroud)

我不明白为什么将我的代码更改为以下更改:

  Dim writeAbleColumns As String() = {"IsSelected", "IsFeeExpense", "IsSubscriptionRedemption"}
  With grid
     For Each column As DataGridViewColumn In …
Run Code Online (Sandbox Code Playgroud)

.net vb.net

4
推荐指数
1
解决办法
3278
查看次数

C#Threading ...不明白为什么我的循环为5;

class Thread1_8
{
    static int shared_total;
    static int thread_count;
    static readonly object locker = new object();

    static void Main()
    {
        int[,] arr = new int[5, 5] { { 1,2,3,4,5}, {5,6,7,8,9}, {9,10,11,12,13}, {13,14,15,16,17}, { 17,18,19,20,21} };

        for(int i = 0; i < 5; i++)
        {
            new Thread(() => CalcArray(i, arr)).Start();
        }


        while(thread_count < 5)
        {

        }
        Console.WriteLine(shared_total);
    }

    static void CalcArray(int row, int[,] arr)
    {

        int length = arr.GetLength(0);
        int total = 0;
        for(int j = 0; j < length; j++) …
Run Code Online (Sandbox Code Playgroud)

c#

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

闭包对循环变量的正确语义是什么?

考虑以下lua代码:

f = {}

for i = 1, 10 do
    f[i] = function()
        print(i .. " ")
    end
end

for k = 1, 10 do
    f[k]()
end
Run Code Online (Sandbox Code Playgroud)

这将打印从1到10的数字.在这种情况下,i将关闭外部循环的每次迭代的值.这就是我一直都懂得闭合的方式,我很开心......

...直到我将一些lua代码移植到c#中,我试图做同样的事情:

var f = new Action[10];

for (int i = 0; i < 10; i++)
{
    f[i] = (new Action(delegate()
    {
        Console.Write(i + " ");
    }));
}
for (int k = 0; k < 10; k++)
{
    f[k]();
}
Run Code Online (Sandbox Code Playgroud)

现在我将10号打印10次(让我们忘记了lua数组是基于1的).实际上,在这种情况下,闭包对变量起作用,而不是它的值,这很有意义,因为我只是在第一个循环结束后调用函数.

JavaScript似乎具有相同的语义(接近变量):

var f = []

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

javascript c# lua closures lambda-calculus

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

在c#中同时运行相同方法的多个实例而不会丢失数据?

我真的不太了解任务和线程.我在嵌套的三个级别中有一个方法for,我希望在不同的线程/任务中多次运行,但是我传递给方法的变量变得疯狂,让我用一些代码解释一下:

List<int> numbers=new List<int>();
for(int a=0;a<=70;a++)
{
  for(int b=0;b<=6;b++)
  {
    for(int c=0;b<=10;c++)
    {
        Task.Factory.StartNew(()=>MyMethod(numbers,a,b,c));
    }
  }
}
private static bool MyMethod(List<int> nums,int a,int b,int c)
{
    //Really a lot of stuff here
}
Run Code Online (Sandbox Code Playgroud)

这是嵌套,myMethod确实做了很多事情,比如计算一些数字的阶乘,写入不同的文档和匹配响应与组合列表并调用其他小方法,它也有一些返回值(布尔值),但我此刻不要关心他们.问题是没有任务达到目的,就像每次嵌套调用它自己刷新的方法一样,删除以前的实例.它还会给出一个错误,"尝试除以0",其值超过由FORs分隔的值,例如a=71, b=7, c=11所有变量都为空(这就是除以零的原因).我真的不知道如何解决它.

c# task task-parallel-library taskfactory

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