C#完成后可以将事件连接到方法吗?

时间:2010-04-08 09:31:45

标签: c#

我有一个.dll文件,在那里,有一个名为A的方法。当我调用该方法时,我想调用我自己的方法,方法B.所以我的问题是,是否可以调用方法方法A完成后立即B?

Offcourse我可以调用方法A,然后手动调用方法B.但我想知道有没有办法自动执行此操作,也许有一个事件?因此,当方法A完成时,事件会以某种方式被触发,并且调用方法A.

编辑: 我无法控制.dll。所以我无法改变方法A中的任何内容。

6 个答案:

答案 0 :(得分:3)

请看Aspect Oriented Programming (AOP),特别是PostSharp

http://www.sharpcrafters.com/aop.net/msil-injection

  

MSIL注射,或MSIL插入,是   修改MSIL的过程   现有方法的说明。   有人说我们注射或插入   现有的新指令   流动。

答案 1 :(得分:1)

如果你控制了定义方法A的类,那么我会选择事件方法。以下是MSDN Event Naming Guidelines之后的简短示例:

class Foo
{
    public event EventHandler Did;

    public void Do()
    {
        Console.WriteLine("Do");

        this.OnDid(EventArgs.Empty);
    }

    protected void OnDid(EventArgs e)
    {
        var evt = this.Did;

        if (evt != null)
        {
            evt(this, e);
        }
    }
}

class Program
{
    public static void Main(string[] args)
    {
        var foo = new Foo();

        foo.Did += (sender, e) => Console.WriteLine("Did");

        foo.Do();
    }
}

如果要为定义B的类的每个实例运行方法A,可以创建辅助方法来创建实例并立即添加事件处理程序。

public static Foo CreateFoo()
{
    var foo = new Foo();

    foo.Did += (sender, e) => Console.WriteLine("Did");

    return foo;
}

答案 2 :(得分:1)

只有目标方法的合作(它调用委托或触发事件)或调用者(用调用方法的中间方法替换对A的调用)。

你也可以重新编写IL来修改A以允许这样的回调(或理论上使用调试器API),但这要复杂得多。

包装器方法类似于:

var AWrapped = () => { A(); MyHelper(); };

并使用A或更明确地将所有来电替换为AWrapped

原始来电者代码:

//...
A();
//...

并替换为:

//...
AWrapped();
//...

(如果要在多个地方使用,或者在多种类型中使用,那么我会使用静态函数(可能是扩展函数)来进行包装。)

答案 3 :(得分:1)

如果您无法控制dll,请编写包装类

public class WrapAnotherClass : AnotherClass
{
    public EventHandler DoSomethingFinished;

    public new void DoSomething()
    {
        base.DoSomething();

        var temp = DoSomethingFinished;
        if (temp != null)
        {
            temp(this, EventArgs.Empty);
        }
    }
}

public class AnotherClass
{
    public void DoSomething()
    {
        Console.WriteLine("Do something!");
    }
}

答案 4 :(得分:0)

如果方法A允许依赖注入,则可以通过注入自己的依赖项来实现。怎么样?可能其他擅长它的人可以告诉你,如果你的方法A允许依赖。我不擅长。

其次,您可以扩展包含方法A的类(如果它未密封)并覆盖方法A的功能以连接事件。现在到处使用扩展类的实例来调用方法A

答案 5 :(得分:0)

看到你无法访问代码,你必须创建一个包装器来封装它。

像这样:

class Wrapper
{
   private A = new A(); //this is your closed .dll class

   public event EventHandler DoneThing;

   private void OnDoneThing()
   {
      if(DoneThing!=null)
      {
        DoneThing(this, EventArgs.Empty);
      }
   }

   public void DoThing()
   {
       A.DoThing();
       OnDoneThing();
   }
}