【问题标题】:Dynamically injecting a parameter into a function call in c#在c#中将参数动态注入函数调用
【发布时间】:2010-02-09 18:47:42
【问题描述】:

我想知道是否可以在运行时动态注入函数参数。例如我有一个有两个重载方法的类说

Class C1
{
    public static void Func1(object o)
    {
    }

    public static void Func1()
    {
    }       
}

Class C2
{

    public void Func1()
    {
       C1.Func1();
    }
}

现在,是否可以通过调用重载方法 C1.Func1(object o) 动态替换对 Func1() 的调用,并传入 'this' 或类型对象作为参数。

所以,当我调用 C1.Func1() 时,我的代码应该调用 C1.Func1(this);

【问题讨论】:

  • 我猜他想拦截/分流一段他没有源代码访问权限但知道公众的已编译代码。
  • 一种方法是将 exe 反编译为 MSIL,进行更改并重新编译。

标签: c# dynamic parameters


【解决方案1】:

我假设“动态”是指编译后的解决方案,但不一定在运行时。后者将更具挑战性,但可以做到。对于前者,如果您了解一些 IL,则相当容易。我注意到C2.Func1 编译为类似

.method public hidebysig instance void Func1() cil managed {
    call void SomeNamespace.C1::Func1() 
    ret 
}

您可以轻松替换为

.method public hidebysig instance void Func1() cil managed {
    ldarg.0
    call void SomeNamespace.C1::Func1(object)
    ret 
}

这是因为实例方法中的参数 0 始终是当前实例的 this 引用,我们可以使用指令 ldarg.0 将其压入堆栈。此外,我们只需将我们正在调用的方法的签名从无参数方法替换为接受单个 object 作为参数的方法。

您可以使用 ildasm 轻松反编译为 IL,然后使用 ilasm 重新编译。

【讨论】:

  • 谢谢 Jason,这确实有效,但是您能否详细解释一下您建议的其他选项,即在运行时,这是否意味着使用 Am 建议的 Profiler API?
【解决方案2】:

你可以使用扩展方法:

public static class C1Extensions
{
    public static void Func1(this C1 o)
    {
        // ...
    }
}

public class C1
{
    public void Foo()
    {
       this.Func1();
    }
}

【讨论】:

  • +1,正要发同样的东西,但是,仍然需要“this”关键字来调用它。
【解决方案3】:

几个选项:

  1. 将二进制文件反编译为 MSIL,手动进行更改并重新编译。
  2. 使用 .NET 分析 API 来注入代码,这里有一篇 [文章] 讨论它。
  3. 类似问题code-injection-with-c

代码注入就是拦截不带参数的函数,调用带参数的函数。

【讨论】:

    【解决方案4】:

    由于您的方法是静态的,因此无法获取调用对象。

    您的选择是使您的方法成为非静态方法并创建一个 C1 对象,或者将 C2 (this) 对象作为参数传递。

    【讨论】:

      【解决方案5】:

      您是否考虑过使用扩展方法来做到这一点?

      public static class C1WrappingExtensions {
          public static void Func1(this object instance) {
              C1.Func(instance);
          }
      }
      
      // Now you can just call Func1() on any object...
      var me = new Whatever();
      me.Func1();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-30
        • 2015-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-30
        • 2014-12-21
        相关资源
        最近更新 更多