No entanto, a assinatura da função nem sempre é a mesma, tendo, portanto, diferentes quantidades de argumentos.
Vamos começar com algumas funções definidas assim:
private object Function1() { return null; }
private object Function2(object arg1) { return null; }
private object Function3(object arg1, object arg3) { return null; }
Você realmente tem 2 opções viáveis à sua disposição:
1) Mantenha a segurança de tipo fazendo com que os clientes chamem sua função diretamente.
Esta é provavelmente a melhor solução, a menos que você tenha muito boas razões para quebrar a partir deste modelo.
Quando você fala sobre como interceptar chamadas de função, parece-me que você está tentando reinventar funções virtuais. Existem várias maneiras de tirar esse tipo de funcionalidade da caixa, como herdar de uma classe base e substituir suas funções.
Parece-me que você quer uma classe que seja mais um wrapper do que uma instância derivada de uma classe base, então faça algo assim:
public interface IMyObject
{
object Function1();
object Function2(object arg1);
object Function3(object arg1, object arg2);
}
class MyObject : IMyObject
{
public object Function1() { return null; }
public object Function2(object arg1) { return null; }
public object Function3(object arg1, object arg2) { return null; }
}
class MyObjectInterceptor : IMyObject
{
readonly IMyObject MyObject;
public MyObjectInterceptor()
: this(new MyObject())
{
}
public MyObjectInterceptor(IMyObject myObject)
{
MyObject = myObject;
}
public object Function1()
{
Console.WriteLine("Intercepted Function1");
return MyObject.Function1();
}
public object Function2(object arg1)
{
Console.WriteLine("Intercepted Function2");
return MyObject.Function2(arg1);
}
public object Function3(object arg1, object arg2)
{
Console.WriteLine("Intercepted Function3");
return MyObject.Function3(arg1, arg2);
}
}
2) OU mapeie a entrada de suas funções para uma interface comum.
Isso pode funcionar se todas as suas funções estiverem relacionadas. Por exemplo, se você está escrevendo um jogo e todas as funções fazem algo para alguma parte do jogador ou inventário do jogador. Você acabaria com algo assim:
class Interceptor
{
private object function1() { return null; }
private object function2(object arg1) { return null; }
private object function3(object arg1, object arg3) { return null; }
Dictionary<string, Func<State, object>> functions;
public Interceptor()
{
functions = new Dictionary<string, Func<State, object>>();
functions.Add("function1", state => function1());
functions.Add("function2", state => function2(state.arg1, state.arg2));
functions.Add("function3", state => function3(state.arg1, state.are2, state.arg3));
}
public object Invoke(string key, object state)
{
Func<object, object> func = functions[key];
return func(state);
}
}