首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用类截取委托调用

如何使用类截取委托调用
EN

Stack Overflow用户
提问于 2015-08-25 18:01:31
回答 3查看 343关注 0票数 2

基本上,我想归档的是截获对委托的调用的方法。我在考虑定义一个可以用于它的类。类似于:

代码语言:javascript
运行
复制
timer.Elapsed += new MyClass((sender, e)=> { /* do stuff */});

如何以通用的方式定义MyClass

我可以让Myclass继承自ElapsedEventHandler,但是它只能用于这个事件。我在考虑让MyClass继承自Action<object, EventArg>,因为您还可以编写

代码语言:javascript
运行
复制
timer.Elapsed += (sender, e) => { /* do stuff */ }

但我没有让它工作。有什么建议吗?

EN

回答 3

Stack Overflow用户

发布于 2015-08-25 18:09:45

您不能创建将被委托的类,但是您可以从您的类创建一个委托。

考虑一个类:

代码语言:javascript
运行
复制
public class MyClass 
{
    public void OnTimerElapsed(object sender, EventArgs e)
    {
    }
}

现在将您的类方法连接到事件:

代码语言:javascript
运行
复制
var obj = new MyClass();
timer.Elapsed += obj.OnTimerElapsed;

您还可以断开它的连接:

代码语言:javascript
运行
复制
timer.Elapsed -= obj.OnTimerElapsed;

您应该阅读更多关于C#中的事件的内容,比如这里:https://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx

票数 3
EN

Stack Overflow用户

发布于 2015-08-25 18:06:06

你不能--在C#的类型系统中,两个委托之间没有关系,即使他们的签名匹配。

例如,Func<T, bool>Predicate<T>是不相关的。

此外,假设表达式(sender, e) => { /* do stuff */}的类型为Action<object, EventArg>是错误的。Lambda表达式本身没有类型。它们将根据上下文转换为委托。

这就是为什么不能将lambda表达式赋值给var -因为类型无法推断-因为没有类型。

代码语言:javascript
运行
复制
var del = (int i) => i + 1;         //incorrect
Func<int, int> del = i => i + 1;    //correct
CustomDelegate del = i => i + 1;    //correct


delegate int CustomDelegate(int i);
票数 2
EN

Stack Overflow用户

发布于 2015-08-25 18:38:55

好的。这很棘手。但我不得不说..。通过使用隐式转换的奇妙世界,这是可能的。试着这样开始..

代码语言:javascript
运行
复制
// define a new class called EventCall
public class EventCall<T> {
    // this one will be returned to be executed directly after your initialization
    public T Handler { get; private set; }

    public EventCall(T handler) {
        if (handler == null) throw new ArgumentNullException("handler");
        this.Handler = handler;
        // the intercept code can be inserted here..
        // but i can't see any point of doing this..
    }

    // this method will return the handler directly after the initialization
    public static implicit operator T(EventCall<T> c) {
        return this.Handler;
    }
}

// now you can use it like
timer.Elapsed += new EventCall<ElapsedEventHandler>((sender, args) => { /* code to invoke */ });

这个可以用。我刚刚自己测试过了。但是类型参数T总是需要匹配正确的事件处理程序类型。

这段代码基本上是使用T参数来获取新对象的类型,该类型直接传递给构造函数,然后(通过隐式转换)立即返回。这有点过火了..。但不管怎样。希望这会有帮助..。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32201022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档