无法在没有附加处理程序的C#中触发事件.因此,在每次调用之前,有必要检查事件是否为空.
if ( MyEvent != null ) {
MyEvent( param1, param2 );
}
Run Code Online (Sandbox Code Playgroud)
我想保持我的代码尽可能干净,并摆脱那些空检查.我不认为这会影响性能,至少在我的情况下不会.
MyEvent( param1, param2 );
Run Code Online (Sandbox Code Playgroud)
现在我通过手动为每个事件添加一个空的内联处理程序来解决这个问题.这很容易出错,因为我需要记住这样做等等.
void Initialize() {
MyEvent += new MyEvent( (p1,p2) => { } );
}
Run Code Online (Sandbox Code Playgroud)
有没有办法使用反射和一些CLR魔法自动为给定类的所有事件生成空处理程序?
我看到代表有两种形式:
A. Func<string, string> convertMethod = lambda
B. public delegate string convertMethod(string value);
Run Code Online (Sandbox Code Playgroud)
我不确定这两者之间究竟有什么区别.他们都是代表吗?我相信第一个会使用lambda,第二个必须有一个方法来实际执行工作.我也可能感到困惑.
每个人的利弊是什么?
我应该在哪里专门使用它们?
今天我在考虑宣布这个:
private delegate double ChangeListAction(string param1, int number);
Run Code Online (Sandbox Code Playgroud)
但为什么不用这个:
private Func<string, int, double> ChangeListAction;
Run Code Online (Sandbox Code Playgroud)
或者如果ChangeListAction没有返回值,我可以使用:
private Action<string,int> ChangeListAction;
Run Code Online (Sandbox Code Playgroud)
那么使用delegate关键字声明委托的优势在哪里?
是因为.NET 1.1,随着.NET 2.0的出现Action<T>和.NET 3.5的出现Func<T>?
我正在尝试在摩托罗拉Milestone A853上运行helloandroid应用程序.我输入"adb devices"并正确识别移动设备.但是,当我尝试运行应用程序时,Eclipse总是停留在27%"启动委托".
这可能是什么原因?
在代码审查中,我偶然发现了这个(简化的)代码片段以取消注册事件处理程序:
Fire -= new MyDelegate(OnFire);
Run Code Online (Sandbox Code Playgroud)
我认为这不会取消注册事件处理程序,因为它创建了一个之前从未注册过的新委托.但是搜索MSDN我发现了几个使用这个习惯用法的代码示例.
所以我开始了一个实验:
internal class Program
{
public delegate void MyDelegate(string msg);
public static event MyDelegate Fire;
private static void Main(string[] args)
{
Fire += new MyDelegate(OnFire);
Fire += new MyDelegate(OnFire);
Fire("Hello 1");
Fire -= new MyDelegate(OnFire);
Fire("Hello 2");
Fire -= new MyDelegate(OnFire);
Fire("Hello 3");
}
private static void OnFire(string msg)
{
Console.WriteLine("OnFire: {0}", msg);
}
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,发生了以下情况:
Fire("Hello 1"); 按预期产生了两条消息.Fire("Hello 2");制作了一条消息!new代表工作!Fire("Hello 3");扔了一个NullReferenceException.Fire为null …我已经阅读了很多文章,但我仍然不清楚我们通常创建的普通代表和多播代理之间的区别.
public delegate void MyMethodHandler(object sender);
MyMethodHandler handler = new MyMethodHandler(Method1);
handler += Method2;
handler(someObject);
Run Code Online (Sandbox Code Playgroud)
上面的委托MyMethodHandler将调用这两个方法.现在多播代表的位置在哪里.我已经读过它们可以调用多种方法,但我担心我对代理的基本理解是不正确的.
遵循这个问题 - 使用C#传递方法作为参数和我的一些个人经验我想更多地了解调用委托与仅在C#中调用方法的性能.
虽然代表非常方便,但我有一个应用程序通过委托做了很多回调,当我们重写这个使用回调接口时,我们得到了一个数量级的速度提升.这是使用.NET 2.0所以我不确定3和4的情况如何变化.
如何在编译器/ CLR内部处理对委托的调用,这对方法调用的性能有何影响?
编辑 - 澄清代表与回调接口的含义.
对于异步调用,我的类可以提供一个OnComplete事件和调用者可以订阅的相关委托.
或者,我可以使用调用者实现的OnComplete方法创建一个ICallback接口,然后将其自身注册到类,然后在完成时调用该方法(即Java处理这些事情的方式).
我正在学习C#中的事件/代表.我可以问一下你对我所选择的命名/编码风格的看法(取自Head First C#书)吗?
我明天正在和朋友一起教这个问题,并且正在尝试用最优雅的方式来解释这些概念.(认为理解一门学科的最好方法就是尝试教它!)
class Program
{
static void Main()
{
// setup the metronome and make sure the EventHandler delegate is ready
Metronome metronome = new Metronome();
// wires up the metronome_Tick method to the EventHandler delegate
Listener listener = new Listener(metronome);
metronome.OnTick();
}
}
Run Code Online (Sandbox Code Playgroud)
public class Metronome
{
// a delegate
// so every time Tick is called, the runtime calls another method
// in this case Listener.metronome_Tick
public event EventHandler Tick;
public void OnTick()
{
while (true) …Run Code Online (Sandbox Code Playgroud) 我见过开发人员使用下面的代码.它们之间的确切区别是什么,哪些符合标准?他们是一样的,Action而且Func<T>是一个代表,以及:
public event Action<EmployeeEventAgs> OnLeave;
public void Leave()
{
OnLeave(new EmployeeEventAgs(this.ID));
}
Run Code Online (Sandbox Code Playgroud)
VS
public delegate void GoOnLeave(EmployeeEventAgs e);
public event GoOnLeave OnLeave;
public void Leave()
{
OnLeave(new EmployeeEventAgs(this.ID));
}
Run Code Online (Sandbox Code Playgroud)