Tag: closures

c#表达式中的闭包变量捕获问题

我有一个使用表达式树创建委托的函数。 在这个表达式中,我使用从传入函数的多个参数中捕获的变量。 实际的表达式树相当大,例如: Delegate GenerateFunction(T current, IList parents) { var currentExpr = Expression.Parameter(typeof(T), “current”); var parentsExpr = Expression.Parameter(parents.getType(), “parents”); var parameters = new List(); …. return Expression.Lambda(Expression.Block(new List { parentsExpr, currentExpr }, ….), parameters.ToArray()).Compile(); } 然后,我在将该函数传递给另一个要使用的函数之前,从另一个方法调用此方法。 完成所有操作后,我想访问在表达式树中更新的父项内容。 一切似乎都在编译,我的表达式看起来还不错,但是当我运行它时,我出现(虽然我不能确定)在访问parent变量时(在表达式/闭包内)获取空引用exception。 我想我想知道我做错了什么,或者这是否可行,以及了解发生了什么的提示。 我似乎无法在方法中找到任何悬挂的(?)局部变量,所以我想知道它们是否被捕获了? 谢谢,马克

LinqKit的扩展器是否有一个特殊原因无法从字段中获取表达式?

我正在使用LinqKit库,它允许动态组合表达式。 这是编写Entity Framewok数据访问层的纯粹幸福,因为可以选择重复使用和组合多个表达式,这样就可以实现可读和高效的代码。 考虑以下代码: private static readonly Expression<Func> _selectMessageViewExpr = ( Message msg, int requestingUserId ) => new MessageView { MessageID = msg.ID, RequestingUserID = requestingUserId, Body = ( msg.RootMessage == null ) ? msg.Body : msg.RootMessage.Body, Title = ( ( msg.RootMessage == null ) ? msg.Title : msg.RootMessage.Title ) ?? string.Empty }; 我们声明了一个将Message投影到MessageView上的表达式(为了清楚起见,我删除了细节)。 现在,数据访问代码可以使用此表达式来获取单个消息: […]

multithreading和lambda变量范围

我正在使用一个管理线程池来运行操作的类。 最初它被编码为采取Action(没有参数),我这样称呼它: void LoadTasks() { string param; // some code loops and changes param { threadPool.EnqueueTask(() => SomeMethod(param)); } } 由于线程运行一些很好,但偶尔param变量不是我所期望的…它是一个“更新”的值,而不是我打算发送给该方法。 更改线程池以接受Action并在没有lambda的情况下调用 – 就像这个threadPool.EnqueueTask(SomeMethod, param) – 解决了我的问题。 关于线程安全,我看到了很多关于C#lambdas的问题。 例如,lambdas 的公认答案 比您预期的更不可能是线程安全的。 我发现关于lambdas / closures / scoping的其他问题和答案令人困惑。 所以我正在寻找lambdas和变量范围的解释,理想情况与我的例子中的问题有关。

任务中的秒表似乎是所有任务的附加,想要测量任务间隔

我正在循环运行并以下列方式启动任务: var iResult = new List(); foreach(var i in myCollection) { var task = Task.Factory.StartNew(() => DoSomething(), TaskCreationOptions.LongRunning); task.ContinueWith(m => myResponseHandler(m.Result)); iResult.Add(task); } 在我的DoSomething()方法中,我有一个计时器: public static myMsg DoSomething() { var timer = System.Diagnostics.Stopwatch.StartNew(); DoLongRunningTask(); //If it matters this hits a REST endpoint (https) timer.Stop(); return new myMsg(timer.ElaspedMilliseconds); } 当我遍历myMsg的列表时, myMsg似乎完全是加法的 – 第一个上的ElaspedMilliseconds可能是300,但最后一个可能是50000(50秒) – 这实际上是整个事情需要的大致时间运行(由另一个计时器测量)。

此代码是否真的导致“访问修改后的闭包”问题?

采用以下代码,Resharper告诉我voicesSoFar和voicesNeededMaximum导致“访问修改后的闭包”。 我读到了这些,但令我困惑的是,Resharper建议通过在LINQ查询之前提取变量来解决这个问题。 但这就是他们已经到了的地方! 如果我只是在int voicesSoFar = 0之后添加int voicesSoFar1 = voicesSoFar Resharper就会停止抱怨。 是否有一些我不理解的奇怪逻辑使得Resharper的建议正确无误? 或者有没有办法在这样的情况下安全地“访问修改后的闭包”而不会导致错误? // this takes voters while we have less than 300 voices int voicesSoFar = 0; int voicesNeededMaximum = 300; var eligibleVoters = voters.TakeWhile((p => (voicesSoFar += p.Voices) < voicesNeededMaximum));

C#中的匿名内部类

我正在编写C#Wicket实现,以加深我对C#和Wicket的理解。 我们遇到的一个问题是Wicket大量使用匿名内部类,而C#没有匿名内部类。 因此,例如,在Wicket中,您可以像这样定义一个链接: Link link = new Link(“id”) { @Override void onClick() { setResponsePage(…); } }; 由于Link是一个抽象类,它强制实现者实现onClick方法。 但是,在C#中,由于没有匿名内部类,因此无法执行此操作。 作为替代方案,您可以使用以下事件: var link = new Link(“id”); link.Click += (sender, eventArgs) => setResponsePage(…); 当然,这有一些缺点。 首先,可以有多个Click处理程序,这可能不太酷。 它也不会强制实现者添加Click处理程序。 另一个选择可能是只有一个这样的闭包属性: var link = new Link(“id”); link.Click = () => setResponsePage(…); 这解决了具有许多处理程序的问题,但仍然没有强制实现者添加处理程序。 所以,我的问题是,你如何在惯用的C#中模仿这样的东西?

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

可能重复: 什么是’关闭’? 访问修改后的关闭 获得修改后的封闭(2) Resharper抱怨下面这段代码: foreach (string data in _dataList) DoStuff (() => field); 什么是关闭? 我为什么要关心? 我已经读过关于数学和函数式编程的闭包,我在这里不知所措。 我的大脑太沉重了。 简单来说,这里发生了什么?

C#-Closure -Clarification

我正在学习C#。可以说,闭包是a construct that can adopt the changes in the environment in which it is defined. 示例: List gurus = new List() { new Person{id=1,Name=”Jon Skeet”}, new Person{id=2,Name=”Marc Gravell”}, new Person{id=3,Name=”Lasse”} }; void FindPersonByID(int id) { gurus.FindAll(delegate(Person x) { return x.id == id; }); } 变量id在FindPersonByID()的范围内声明,但我们仍然可以访问匿名函数内的局部变量id (即) delegate(Person x) { return x.id == id; } delegate(Person […]

来自Eric Lippert的博客:“不要关闭循环变量”

可能重复: 为什么在lambda表达式中使用迭代变量很糟糕 C# – foreach标识符和闭包 来自Eric Lippert的2010年6月28日报道 : static IEnumerable<IEnumerable> CartesianProduct(this IEnumerable<IEnumerable> sequences) { // base case: IEnumerable<IEnumerable> result = new[] { Enumerable.Empty() }; foreach(var sequence in sequences) { var s = sequence; // don’t close over the loop variable // recursive case: use SelectMany to build the new product out of the old one […]