InvokeMember löst eine AmbigousMatchException aus

Dieser Artikel hilft Ihnen, das Problem zu beheben, bei dem ein Fehler ausgelöst werden kann, wenn Sie die AmbigousMatchException nicht generische Version der Funktion System.Type.InvokeMember DefaultBinder Check aufrufen.

Ursprüngliche Produktversion:   Microsoft .NET Framework 4.5
Ursprüngliche KB-Nummer:   2843607

Problembeschreibung

Angenommen, Sie verfügen über eine Klasse mit einer generischen Überladung einer Methode, wie im folgenden Beispiel gezeigt:

class Test
{
    public Boolean Check<T>(String Value)
    {
        return false;
    }
    public Boolean Check(String Value)
    {
        return true;
    }
}

Wenn Sie System.Type.InvokeMember aufrufen, die DefaultBinder nicht generische Version der Funktion Check aufzurufen, wird eine AmbigousMatchException ausgelöst.

Ursache

Wenn eine generische Überladung der Methode vorhanden ist, System.Type.DefaultBinder kann nicht zwischen der generischen und der nicht generischen Version der Funktion unterschieden werden.

Lösung

Erstellen Sie ein benutzerdefiniertes Binder, um die nicht generische Überladung der Methode zurückzugeben und sie im Aufruf zu verwenden. Unten finden Sie InvokeMember eine Beispielimplementierung:

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);
    }
}