无论如何,是否可以为 C# 中的各种事件定义单个事件处理程序



我想声明各种事件的通用处理程序,它基本上会将事件路由到应用程序的JavaScript部分。我自己是JS/AS3背景的,这样的事情是一件相对简单的事情。不过,SilverLight和C#看起来相当严格。

计划如下,JS将调用一个特殊的[ScriptableMember],其中包含要实例化的类名和要调用的方法,作为字符串参数。然后,[ScriptableMember] 必须构造类的实例,并选择性地订阅可由该实例触发的事件。要订阅的事件将在某种公共静态结构中公开。[ScriptableMember] 必须从该结构中提取事件属性,并使用单个事件处理程序订阅所有这些属性。然后,常见的单个事件处理程序应将 C# 事件转换为 JS 事件。

显然,一切都应该在某种工厂逻辑中通用化和自动化。

一个大问题是我无法事先知道委托或 EventArgs 对象的类型。即使我知道为每个案例创建超载也会很麻烦。无论如何可以在 C# 中定义通用事件处理程序吗?

更新:

下面是一个处理所描述逻辑的代码片段:

[ScriptableMember]
public void exec(string compName, string action, ScriptObject scriptObject)
{
    String compFQName;
    Type compClass; 
    object comp;    
    compFQName = "fully.qualified.name." + compName;
    compClass = Type.GetType(compFQName);
    if (compClass != null) {
        comp = Activator.CreateInstance(compClass);
        FieldInfo fieldInfo = compClass.GetField("dispatches", BindingFlags.Static | BindingFlags.Public);
        object[] dispatches = (object[])fieldInfo.GetValue(comp);
        if (dispatches != null) {
            foreach (string eventName in dispatches) {
                EventInfo eventInfo = compClass.GetEvent(eventName);
                Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, "OnComponentEvent");
                eventInfo.AddEventHandler(comp, handler);
            }                       
        }
    }
    // ...
}

然后有一个事件处理程序应该赶上所有事件:

public void OnComponentEvent(object sender, EventArgs args)
{
     // do something ...
}

每个事件参数都必须继承自EventArgs类。如果您遵循此规则,则只需像

public void GenericHandler(object sender, EventArgs e)

并订阅任何活动

编辑:就像 O. R. Mapper 所说的那样,如果您的处理程序的签名与上面所说的无法比拟,您可以从订阅您的事件的匿名方法调用它,例如:

public delegate void StupidEventHandler(int walueThatMustBeWrappedToEventArgs);
public event StupidEventHandler StupidEventOccured;
//....
{
    //....
    stupidClass.StupidEventOccured += delegate(int value) { handlerObject.GenericHandler(stupidClass, new StupidEventHandlerWrapper(value)); }
}

编辑:由于该问题建议使用非常用的 .NET 功能,因此处理也是不寻常的。由于您订阅了所有内容,因此您必须知道可能发生哪些事件类型。然后像这样处理它:

public void GenericHandler(object sender, EventArgs e)
{
    if (e is MouseEventArgs)
    {
        var mouseArgs = e as MouseEventArgs;
        // .. process this case
    }
    else if (e is ....)
}

编辑:

要订阅它,请尝试以下操作:

[ScriptableMember]
public void exec(string compName, string action, ScriptObject scriptObject)
{
    String compFQName;
    Type compClass; 
    object comp;    
    compFQName = "fully.qualified.name." + compName;
    compClass = Type.GetType(compFQName);
    if (compClass != null) {
        comp = Activator.CreateInstance(compClass);
        FieldInfo fieldInfo = compClass.GetField("dispatches", BindingFlags.Static | BindingFlags.Public);
        object[] dispatches = (object[])fieldInfo.GetValue(comp);
        if (dispatches != null) {
            foreach (string eventName in dispatches) {
                EventInfo eventInfo = compClass.GetEvent(eventName);
                EventHandler handlerMethod = OnComponentEvent;
                var handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, handlerMethod.Target, handlerMethod.Method);
                eventInfo.AddEventHandler(comp, handler);
            }                       
        }
    }
    // ...
}

为什么你的版本不起作用是一个很大的困惑。

最新更新