Tag: 委托

C#编译器奇怪与委托构造函数

基于以下问题 ,我发现了c#编译器的一些奇怪行为。 以下是有效的C#: static void K() {} static void Main() { var k = new Action(new Action(new Action(K)))); } 我发现奇怪的是编译器’解构’传递的委托。 ILSpy输出如下: new Action(new Action(new Action(null, ldftn(K)), ldftn(Invoke)).Invoke); 可以看出,它会自动决定使用委托的Invoke方法。 但为什么? 实际上,代码不清楚。 我们是否有一个三重包装的委托(实际)或内部委托只是’复制’到外部委托(我最初的想法)。 当然,如果意图就像编译器发出代码一样,那么应该写一下: var k = new Action(new Action(new Action(K).Invoke).Invoke); 与反编译代码类似。 任何人都可以certificate这种“令人惊讶的”转变的原因吗? 更新: 我只能想到一个可能的用例; 委托类型转换。 例如: delegate void Baz(); delegate void Bar(); … var k = […]

为什么我不能使用/强制转换/为ThreadStart?

两者都是委托并具有相同的签名,但我不能将Action用作ThreadStart。 为什么? Action doIt; doIt = () => MyMethod(“test”); Thread t; t = new Thread(doIt); t.Start(); 但这似乎有效: Thread t; t = new Thread(() => MyMethod(“test”)); t.Start();

表达式树和调用委托

所以我有一个delegate指向一些我在第一次创建delegate对象时实际上并不知道的函数。 稍后将该对象设置为某个函数。 然后我还想创建一个表达式树,用参数调用委托(为了这个问题,参数可以是5 )。 这是我正在努力的一点; 下面的代码显示了我想要的但它没有编译。 Func func = null; Expression expr = Expression.Invoke(func, Expression.Constant(5)); 对于这个例子我可以这样做(这很实用,因为我需要在运行时构建表达式树): Func func = null; Expression<Func> expr = () => func(5); 这使expr成为: () => Invoke(value(Test.Program+c__DisplayClass0).func, 5) 这似乎意味着要使用delegate func ,我需要生成value(Test.Program+c__DisplayClass0).func位。 那么,我怎样才能创建一个调用委托的表达式树?

请解释.NET代表

所以我读了MSDN和Stack Overflow。 我理解Action Delegate的一般操作,但无论我做多少例子都不会点击。 一般来说,代表的想法也是如此。 所以这是我的问题。 当你有这样的function: public GetCustomers(Action<IEnumerable,Exception> callBack) { } 这是什么,我应该传递给它什么?

匿名方法作为BeginInvoke的参数?

为什么不能将匿名方法作为参数传递给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 } } 我试图避免宣布代表。 为什么我不能写下面的东西呢? 或者我可以,我只是无法弄清楚正确的语法? 以下目前生成: 参数类型’System.Delegate’不能赋予参数类型’匿名方法’ 好吧,这当然是正确的,但是我可以使用其他一些语法来做到这一点(避免为了使用BeginInvoke()而声明一个单独的委托吗? (能够做到这一点将完全符合使用anon方法/ lamdas代替显式委托的概念,这些委托在其他地方工作得非常干净。) private void ConfigureMainMenu(DIServer server,) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { mnMnu.BeginInvoke( […]

即使签名匹配,也无法将一种类型的委托分配给另一种类型

我的病态好奇让我想知道为什么以下失败: // declared somewhere public delegate int BinaryOperation(int a, int b); // … in a method body Func addThem = (x, y) => x + y; BinaryOperation b1 = addThem; // doesn’t compile, and casting doesn’t compile BinaryOperation b2 = (x, y) => x + y; // compiles!

C# – ThreadPool QueueUserWorkItem使用?

就在我现在使用以下代码添加排队的线程。 我不喜欢它。 而且我的同事也不会因为他们不太了解C#。 我想要的当然是将一个方法排队在一个新线程中执行。 private static void doStuff(string parameter) { // does stuff } // call (a) ThreadPool.QueueUserWorkItem(a => doStuff(“hello world”)); // call (b) ThreadPool.QueueUserWorkItem(delegate { doStuff(“hello world”); }); 那么ThreadPool.QueueUserWorkItem还有其他用途吗? 最好的是另一个1-Line-Call。 如果可能,使用Func或Action 。 编辑:得到(b)答案和评论,我已经更喜欢它了。

C#中的Typesafe即发即弃异步委托调用

我最近发现自己需要一种类型安全的“即发即忘”机制来异步运行代码。 理想情况下,我想要做的是: var myAction = (Action)(() => Console.WriteLine(“yada yada”)); myAction.FireAndForget(); // async invocation 不幸的是,在没有相应的EndInvoke() BeginInvoke()情况下调用BeginInvoke()的明显选择不起作用 – 它导致资源泄漏缓慢(因为asyn状态由运行时保持并且从未释放…它期望最终调用EndInvoke() 。我也无法在.NET线程池上运行代码,因为它可能需要很长时间才能完成(建议只在线程池上运行相对短暂的代码) – 这使得它无法使用ThreadPool.QueueUserWorkItem() 。 最初,我只对签名与Action , Action或Func匹配的方法只需要此行为。 所以我把一组扩展方法(见下面的清单)放在一起,让我这样做而不会遇到资源泄漏。 每个版本的Action / Func都有重载。 不幸的是,我现在想将此代码移植到.NET 4,其中Action和Func上的generics参数的数量已大幅增加。 在我编写T4脚本来生成这些之前,我还希望找到一种更简单,更优雅的方法来实现这一点。 欢迎任何想法。 public static class AsyncExt { public static void FireAndForget( this Action action ) { action.BeginInvoke(OnActionCompleted, action); } public static void FireAndForget( this Action […]

分配null是否从对象中删除所有事件处理程序?

我在class上定义了新成员 protected COMObject.Call call_ = null; 这个类有我订阅的以下事件处理程序 call_.Destructed += new COMObject.DestructedEventHandler(CallDestructedEvent); 将我的成员设置为null,如下所示删除事件处理程序? call_ = null; 或者我必须取消订阅 – =?

C#事件处理程序委托中的闭包?

我现在来自function编程背景,如果我不理解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); } 我期望文本”I am button number ” + i在for循环的迭代中用i的值关闭。 但是,当我实际运行程序时,每个Button都说I am button number 7 。 我错过了什么? 我正在使用VS2005。 编辑:所以我想我的下一个问题是,如何捕捉价值?