1 and 2 have been answered more than once. So i'll attempt 3.
C# does not provide an unknown method method because it doesn't have to. If you call the Method directly like a.NonExistentMethod()
then the program simply wont compile, and the idea of catching the bad call at runtime is irrelevant.
As you have already found out though it it possible to call methods dynamically at runtime by doing a.GetType().GetMethod("NonExistentMethod").Invoke(a, new object[0])
. This will fail with a NullReferenceException
because the call to GetMethod
returns null. However this situation is detectable, and so maybe we can do something about it. Here is an extension method that behaves as much like PHP as possible. Please note that this is untested, and should never be used in production (or probably even experimental) code.
This can by used by doing this a.CallOrDefault("method name", arg1, arg2);
public static class PhpStyleDynamicMethod
{
public static void __call(Type @class, object[] parameters)
{
// Do stuff here.
}
public static object CallOrDefault(this object b, string method, params object[] parameters)
{
var methods = b.GetType().GetMethods().Where(m => m.Name == method && DoParametersMatch(m.GetParameters(), parameters));
var count = methods.Count();
if (count == 1)
return methods.Single().Invoke(b, parameters);
if (count > 1)
throw new ApplicationException("could not resolve a single method.");
__call(b.GetType(), parameters);
return null;
}
public static bool DoParametersMatch(ParameterInfo[] parameters, object[] values)
{
if (parameters == null && values == null) return true;
if (parameters == null) return false;
if (values == null) return false;
if (parameters.Length != values.Length) return false;
for(int i = 0; i < parameters.Length; i++)
{
var parameter = parameters[i];
var value = values[i];
if (!parameter.GetType().IsAssignableFrom(value.GetType()))
return false;
}
return true;
}
}