Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article helps you resolve the problem where an AmbigousMatchException may be thrown when you call System.Type.InvokeMember using the DefaultBinder to invoke the non-generic version of the function Check.
Original product version: Microsoft .NET Framework 4.5
Original KB number: 2843607
Symptoms
Assume that you have a class that has a generic overload of a method, as shown in the following sample:
class Test
{
public Boolean Check<T>(String Value)
{
return false;
}
public Boolean Check(String Value)
{
return true;
}
}
If you call System.Type.InvokeMember using the DefaultBinder to invoke the non-generic version of the function Check, an AmbigousMatchException is thrown.
Cause
If there's a generic overload of the method, the System.Type.DefaultBinder can't differentiate between the generic and non-generic version of the function.
Resolution
Create a custom Binder to return the non-generic overload of the method and use it in the InvokeMember call, a sample implementation is below:
public class MyBinder : Binder
{
public MyBinder()
: base()
{ }
public override FieldInfo BindToField(
BindingFlags bindingAttr,
FieldInfo[] match,
object value,
CultureInfo culture
)
{
return System.Type.DefaultBinder.BindToField(bindingAttr, match, value, culture);
}
public override MethodBase BindToMethod(
BindingFlags bindingAttr,
MethodBase[] match,
ref object[] args,
ParameterModifier[] modifiers,
CultureInfo culture,
string[] names,
out object state
)
{
if (match == null)
throw new ArgumentNullException();
List<MethodBase> match2 = new List<MethodBase>();
for (int i = 0; i < match.Length; i++)
{
if (!match[i].IsGenericMethod)
{
match2.Add(match[i]);
}
}
return System.Type.DefaultBinder.BindToMethod(bindingAttr, match2.ToArray<MethodBase>(), ref args, modifiers, culture, names, out state);
}
public override object ChangeType(
object value,
Type myChangeType,
CultureInfo culture
)
{
return System.Type.DefaultBinder.ChangeType(value, myChangeType, culture);
}
public override void ReorderArgumentArray(
ref object[] args,
object state
)
{
// Return the args that had been reordered by BindToMethod.
System.Type.DefaultBinder.ReorderArgumentArray(ref args, state);
}
public override MethodBase SelectMethod(
BindingFlags bindingAttr,
MethodBase[] match,
Type[] types,
ParameterModifier[] modifiers
)
{
return System.Type.DefaultBinder.SelectMethod(bindingAttr, match, types, modifiers);
}
public override PropertyInfo SelectProperty(
BindingFlags bindingAttr,
PropertyInfo[] match,
Type returnType,
Type[] indexes,
ParameterModifier[] modifiers
)
{
return System.Type.DefaultBinder.SelectProperty(bindingAttr, match, returnType, indexes, modifiers);
}
}