Jednak sygnatura funkcji nie zawsze jest taka sama, przez co ma różną liczbę argumentów.
Zacznijmy od kilku funkcji zdefiniowanych w ten sposób:
private object Function1() { return null; }
private object Function2(object arg1) { return null; }
private object Function3(object arg1, object arg3) { return null; }
Naprawdę masz do dyspozycji 2 realne opcje:
1) Zachowaj bezpieczeństwo typów, prosząc klientów o bezpośrednie wywoływanie Twojej funkcji.
To chyba najlepsze rozwiązanie, chyba że masz bardzo dobre powody, by oderwać się od tego modelu.
Kiedy mówisz o chęci przechwytywania wywołań funkcji, wydaje mi się, że próbujesz ponownie wymyślić funkcje wirtualne. Istnieje mnóstwo sposobów na uzyskanie tego rodzaju funkcjonalności po wyjęciu z pudełka, takich jak dziedziczenie z klasy bazowej i nadpisywanie jej funkcji.
Wydaje mi się, że potrzebujesz klasy, która jest bardziej opakowaniem niż wyprowadzona instancja klasy bazowej, więc zrób coś takiego:
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) LUB zmapuj wejście funkcji do wspólnego interfejsu.
Może to zadziałać, jeśli wszystkie funkcje są ze sobą powiązane. Na przykład, jeśli piszesz grę, a wszystkie funkcje robią coś z jakąś częścią ekwipunku gracza lub gracza. Skończyłbyś z czymś takim:
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);
}
}