Динамическое внедрение параметра в вызов функции в c # - PullRequest
2 голосов
/ 09 февраля 2010

Мне было интересно, можно ли динамически ввести параметр функции во время выполнения. Например, У меня есть класс с двумя перегруженными методами скажем

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

    public static void Func1()
    {
    }       
}

Class C2
{

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

Теперь можно ли динамически заменить вызов Func1 () на вызов перегруженного метода C1.Func1 (объект o), передав в качестве параметра либо this, либо объект типа.

Итак, когда я вызываю C1.Func1 (), мой код должен вызывать C1.Func1 (this);

Ответы [ 5 ]

3 голосов
/ 09 февраля 2010

Я предполагаю, что под "динамическим" вы подразумеваете решение после компиляции, но не обязательно во время выполнения. Последнее будет более сложным, но может быть сделано. Для первых это довольно легко, если вы знаете какой-нибудь 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 
}

Это потому, что нулевой аргумент в методе экземпляра всегда является ссылкой this для текущего экземпляра, и мы можем поместить его в стек с помощью инструкции ldarg.0. Более того, мы просто заменяем сигнатуру метода, который мы вызываем из метода без параметров, на метод, принимающий в качестве параметра один object.

Вы можете легко декомпилировать в IL, используя ildasm, и перекомпилировать, используя ilasm.

2 голосов
/ 09 февраля 2010

Вы можете использовать метод расширения:

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

public class C1
{
    public void Foo()
    {
       this.Func1();
    }
}
1 голос
/ 09 февраля 2010

Несколько вариантов:

  1. Декомпилируйте двоичный файл в MSIL, внесите изменения вручную и перекомпилируйте его.
  2. Пользователь использует API профилирования .NET для внедрения кода, здесь [статья] обсуждает его.
  3. Аналогичная проблема код-инъекция с-c

Внедрение кода должно было бы перехватить функцию без аргумента и вызвать функцию с аргументом.

0 голосов
/ 09 февраля 2010

Задумывались ли вы об использовании методов расширения для этого?

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();
0 голосов
/ 09 февраля 2010

Поскольку ваш метод статичен, нет способа получить вызывающий объект.

Вы можете либо сделать ваши методы нестатичными и создать объект C1, либо передать объект C2 (this) в качестве параметра.

...