我有以下代码:
public List<IWFResourceInstance> FindStepsByType(IWFResource res)
{
List<IWFResourceInstance> retval = new List<IWFResourceInstance>();
this.FoundStep += delegate(object sender, WalkerStepEventArgs e)
{
if (e.Step.ResourceType == res) retval.Add(e.Step);
};
this.Start();
return retval;
}
Run Code Online (Sandbox Code Playgroud)
请注意我如何将我的事件成员(FoundStep)注册到本地就地匿名函数.
我的问题是:当函数'FindStepByType'结束时 - 匿名函数是否会从事件的委托列表中自动删除,或者我必须在逐步退出函数之前手动删除它?(我该怎么做?)
我希望我的问题很明确.
这是由如何比较TFunc/TProc包含对象的功能/过程?,特别是大卫对巴里问题的评论.由于我没有博客发布这个问题,我将在这里提出这个问题并回答.
问题:Delphi的匿名方法中何时以及如何引用变量?
例:
procedure ProcedureThatUsesAnonymousMethods;
var V: string;
F1: TFunc<string>;
F2: TFunc<string>;
begin
F1 := function: string
begin
Result := V; // references local variable
end
V := '1';
F2 := function: string
begin
Result := V;
end
V := '2';
ShowMessage(F1);
ShowMessage(F2);
end;
Run Code Online (Sandbox Code Playgroud)
两者ShowMessage都将展示2.为什么?如何V捕获以及何时捕获?
我是所有匿名功能的新手,需要一些帮助.我有以下工作:
public void FakeSaveWithMessage(Transaction t)
{
t.Message = "I drink goats blood";
}
public delegate void FakeSave(Transaction t);
public void SampleTestFunction()
{
Expect.Call(delegate { _dao.Save(t); }).Do(new FakeSave(FakeSaveWithMessage));
}
Run Code Online (Sandbox Code Playgroud)
但这完全是丑陋的,我想让Do的内部成为匿名方法,甚至是lambda,如果有可能的话.我试过了:
Expect.Call(delegate { _dao.Save(t); }).Do(delegate(Transaction t2) { t2.Message = "I drink goats blood"; });
Run Code Online (Sandbox Code Playgroud)
和
Expect.Call(delegate { _dao.Save(t); }).Do(delegate { t.Message = "I drink goats blood"; });
Run Code Online (Sandbox Code Playgroud)
但这些给了我
无法将匿名方法转换为类型'System.Delegate',因为它不是委托类型**编译错误.
我究竟做错了什么?
由于马克·英格拉姆发布的内容,似乎是最好的答案,尽管没有人明确说过,但这样做是:
public delegate void FakeSave(Transaction t);
Expect.Call(delegate { _dao.Save(t); }).Do( new FakeSave(delegate(Transaction t2) { t.Message = expected_msg; }));
Run Code Online (Sandbox Code Playgroud) 我现在来自功能编程背景,如果我不理解C#中的闭包,请原谅我.
我有以下代码来动态生成获取匿名事件处理程序的按钮:
for (int i = 0; i < 7; i++)
{
Button newButton = new Button();
newButton.Text = "Click me!";
newButton.Click += delegate(Object sender, EventArgs e)
{
MessageBox.Show("I am button number " + i);
};
this.Controls.Add(newButton);
}
Run Code Online (Sandbox Code Playgroud)
我希望"I am button number " + i用ifor循环的迭代值关闭文本.但是,当我实际运行程序时,每个Button都会说I am button number 7.我错过了什么?我正在使用VS2005.
编辑:所以我想我的下一个问题是,如何捕捉价值?
是否有相当于ForEach方法中的continue语句?
List<string> lst = GetIdList();
lst.ForEach(id =>
{
try
{
var article = GetArticle(id);
if (article.author.contains("Twain"))
{
//want to jump out of the foreach now
//continue; **************this is what i want to do*******
}
//other code follows
}
Run Code Online (Sandbox Code Playgroud)
编辑: 谢谢你所有的好答案.并且感谢您澄清.foreach不是一种扩展方法.我使用这种结构来保持编码风格的一致性(一个不同的程序员在同一个类中使用另一个类似的方法)...并且感谢为什么要避免使用.foreach的链接.
我开发并维护一个用C#2.0编写的大型(500k + LOC)WinForms应用程序.它是多用户,目前部署在大约15台机器上.系统的开发正在进行中(可以被认为是一个永久的测试版),并且很少有人能够保护用户免受可能在每周构建中引入的潜在新错误的影响.
出于这个原因,我发现自己变得非常依赖于调试器中的编辑和继续.它不仅有助于寻找漏洞和修复漏洞,而且在某些情况下还可以进行持续开发.我发现能够在正在运行的应用程序的上下文中执行新编写的代码非常有价值 - 不需要重新编译并为新代码添加特定的入口点(必须添加虚拟菜单选项,按钮等等)应用程序并记住在下一个生产构建之前删除它们 - 所有内容都可以在不停止进程的情况下实时进行测试和测试.
我坚持编辑并继续这么高的考虑,我积极地编写代码以完全兼容它.例如,我避免:
yield(实用程序代码除外)现在,我完全清楚C#3和4中的新语言功能在很大程度上与编辑和继续(lambda表达式,LINQ等)不兼容.这是我拒绝将项目迁移到更新版本的框架的原因之一.
我的问题是,避免使用这些更高级的结构来支持非常非常容易调试的代码是否是一种好的做法?这种发展是否合法,还是浪费?另外,重要的是,这些构造中的任何一个(lambda表达式,匿名方法等)是否会产生性能/内存开销,这些代码可以避免编写良好,编辑和继续兼容的代码?...或者C#编译器的内部工作方式是否使这些高级构造比手动编写的"扩展"代码运行得更快?
如何使用RemoveHandler匿名方法?
这是我为MyEvent类的事件添加处理程序的方法MyClass:
AddHandler MyClass.MyEvent, Sub()
'...
End Sub
Run Code Online (Sandbox Code Playgroud)
然后我如何使用RemoveHandler删除MyEvent事件的处理程序?
我有一个缓存在内存中的DataTable /集合,我想用它作为源来生成自动完成文本框的结果(当然使用AJAX).我正在评估各种选项以快速获取数据.数据表中集合/行中的项目数可以从10000到2,000,000不等.(因此,我们不会转移,暂时假设已做出决定,我有足够的RAM,我将使用缓存而不是数据库查询)
我有一些额外的业务逻辑用于此处理; 我必须priority根据集合中的列(int)确定自动完成列表的优先级.因此,如果我有人搜索Micro并且我会说出20个以单词/句子开头的结果,Micro那么我会选择具有最高优先级的前10个结果项.(因此需要具有与字符串值相关联的优先级属性).
集合项已按字母顺序排序.
在这种情况下,什么是最好的解决方案.
1.使用DataTable.Select(
2. 使用DataTable.Rows.Find( .
3.使用自定义集合与的foreach或通过其值进行迭代.
4.使用泛型集合与匿名委托或lambda(因为两者给予同样的性能或不?)
为什么不能将匿名方法作为参数传递给BeginInvoke方法?我有以下代码:
private delegate void CfgMnMnuDlg(DIServer svr);
private void ConfigureMainMenu(DIServer server,)
{
MenuStrip mnMnu = PresenterView.MainMenu;
if (mnMnu.InvokeRequired)
{
mnMnu.BeginInvoke((CfgMnMnuDlg)ConfigureMainMenu,
new object[] { server});
}
else
{
// Do actual work here
}
}
Run Code Online (Sandbox Code Playgroud)
我试图避免宣布代表.为什么我不能写下面的东西呢?或者我可以,我只是无法弄清楚正确的语法?以下目前生成:
参数类型'System.Delegate'不能赋予参数类型'匿名方法'
好吧,这当然是正确的,但我是否可以使用其他语法来做到这一点(避免为了使用而必须声明一个单独的委托BeginInvoke()?
(能够做到这一点将完全符合使用anon方法/ lamdas代替显式委托的概念,这些委托在其他地方干净利落地工作.)
private void ConfigureMainMenu(DIServer server,)
{
MenuStrip mnMnu = PresenterView.MainMenu;
if (mnMnu.InvokeRequired)
{
mnMnu.BeginInvoke( // pass anonymous method instead ?
delegate(DIServer svr) { ConfigureMainMenu(server);},
new object[] { server});
}
else
{
// Do actual work here
}
}
Run Code Online (Sandbox Code Playgroud) 在JavaScript中,看到自调用函数并不罕见:
var i = (function(x) {
return x;
})(42);
// i == 42
Run Code Online (Sandbox Code Playgroud)
虽然我当然没有比较这些语言,但我认为这样的构造可以翻译成C#,只要提供支持的语言版本:
var i = (delegate(int x) {
return x;
})(42);
Run Code Online (Sandbox Code Playgroud)
要么:
var i = ((x) => {
return x;
})(42);
Run Code Online (Sandbox Code Playgroud)
甚至:
var i = (x => x)(42);
Run Code Online (Sandbox Code Playgroud)
但是,每个版本都有错误:
预期的方法名称
自调用匿名方法是否不受支持(由于显式禁止或类型推断不可能),或者我的尝试中是否存在错误?
我冒昧地猜测,因为没有方法声明(Func<T,T>)可以推断出类型,它无法理清隐含的类型,我打算通过名称调用声明的方法,并且真正搞砸了语法.
勘误表
在此问题充斥之前:
var i = new Func<int, int>(x => x)(42);
Run Code Online (Sandbox Code Playgroud)
我应该说我希望利用类型推断,但我认为由于过于隐蔽而可能无法实现.
所以,澄清一下这个问题; 我们知道我们可以var i = new Func<int, int>(x => x)(42);但是如果没有创建实例,或者转换为Func,这可能吗?
用例
对于那些好奇(或有关)的用例是这样的:
var o …Run Code Online (Sandbox Code Playgroud) c# anonymous-methods anonymous-function self-invoking-function
c# ×7
lambda ×4
delegates ×3
.net ×2
.net-3.5 ×1
addhandler ×1
begininvoke ×1
closures ×1
debugging ×1
delphi ×1
delphi-2010 ×1
linq ×1
optimization ×1
scope ×1
vb.net ×1