Reputation:
I have this simple method:
public void CacheDelegate(Object obj, MemberInfo memberInfo)
{
switch (memberInfo.MemberType)
{
case MemberTypes.Field:
var fieldInfo = (FieldInfo) memberInfo;
CacheDelegate(obj, fieldInfo);
break;
case MemberTypes.Property:
var propertyInfo = (PropertyInfo) memberInfo;
CacheDelegate(obj, propertyInfo);
break;
case MemberTypes.Method:
var methodInfo = (MethodInfo) memberInfo;
CacheDelegate(obj, methodInfo);
break;
default:
throw new Exception("Cannot create a delegate for MemberInfo provided.");
}
}
The method above resolves the type of the memberInfo and calls the applicable method from the following:
public void CacheDelegate(Object obj, FieldInfo fieldInfo)
{
// Do stuff...
}
public void CacheDelegate(Object obj, PropertyInfo propertyInfo)
{
// Do stuff...
}
public sealed override void CacheDelegate(Object obj, MethodInfo methodInfo)
{
// Do stuff...
}
The problem is that the last case label, case MemberTypes.Method, doesn't call the CacheDelegate method with the Method Info overload, but calls the CacheDelegate with the Member Info overload instead! So it's basically just calling itself over and over again, recursively. I tried specifying the parameter name, methodInfo: methodInfo when calling the method, but then the Unity engine is telling me the best overloaded method does not contain a parameter named methodInfo.
I'm quite at a loss of why this is happening. Any help would be greatly appreciated.
Upvotes: 5
Views: 5513
Reputation: 3212
Jon Hanna already explained why this is happening, I'll just add on by providing the source spec where you can read the details: https://msdn.microsoft.com/en-us/library/aa691336(v=vs.71).aspx
Here's a few ways you can solve your issue:
object ignoreMe
. This will force the overload to be compatible, however most will agree it's far from elegant.new
. I'm not 100% sure how overload resolution works when method hiding is involved, but it should cause it to use the correct method. Keep in mind that doing this will of course remove it's polymorphism.Upvotes: 2
Reputation: 113342
Overload resolution works as follows.
Starting with the type called on, find the set of methods declared on that type that can be used.
If that set is empty, then try the same with the base type or interfaces declared. Keep moving up the hierarchy until at least one method that matches is found, or else error.
Of the set that is found, use the most specific method. Error if it's a tie.
So, of the four methods, three were declared in this class. Of those three two are not applicable. That leaves only public void CacheDelegate(Object obj, MemberInfo memberInfo)
as clearly the correct class to call, so it is called.
You could use ((BaseType)this).CacheDelegate(obj, methodInfo);
to force the call you want, since the base type has only one CacheDelegate
overload to choose between.
Upvotes: 4