TargetParameterCountException:Nichtübereinstimmung der Parameteranzahl

TargetParameterCountException:Nichtübereinstimmung der Parameteranzahl

Wenn Sie Reflektion verwenden, um eine Methode aufzurufen, können Sie auf diese Ausnahme stoßen:

Diese Ausnahme ist unkompliziert – Sie übergeben nicht die richtige Anzahl von Parametern an MethodInfo.Invoke().

Dieser Artikel zeigt drei verschiedene Fälle, in denen Sie bei der Verwendung von Reflektion auf diese Ausnahme stoßen könnten.

Reflektion zum Aufrufen einer Methode verwenden

Der einfachste Fall ist, wenn Sie eine Methode aufrufen und einfach nicht alle Parameter übergeben. Möglicherweise hat sich die Methodendefinition geändert, oder Sie haben einfach einen der Parameter ausgelassen. Dieser Fehler ist leicht zu machen, da der Compiler Ihnen nicht hilft, ihn zu finden.

Angenommen, Sie haben die folgende Methode, die die Summe zweier Ganzzahlen zurückgibt:

public class Util
{
	public int Add(int a, int b)
	{
		return a + b;
	}
}
Code language: C# (cs)

Der folgende Code verwendet Reflektion, um diese Methode aufzurufen:

Util util = new Util();
int a = 1;
int b = 2;

var method = util.GetType().GetMethod("Add");
var parameters = new object[] { a };

var sum = method.Invoke(util, parameters);
Code language: C# (cs)

Die Methode Util.Add() hat zwei Parameter:a und b. Dieser Code übergibt nur einen der Parameter – a – und wirft daher TargetParameterCountException.

Die Lösung ist einfach, übergeben Sie alle Parameter. In diesem Fall müssen wir einfach b übergeben.

Util util = new Util();
int a = 1;
int b = 2;

var method = util.GetType().GetMethod("Add");
var parameters = new object[] { a, b };

var sum = method.Invoke(util, parameters);
Code language: C# (cs)

Reflektion verwenden, um eine Methode mit Standardparametern aufzurufen

Standardparameter funktionieren bei Reflektion nicht gleich. Wenn Sie eine Methode mit Standardparametern haben und versuchen, sie mit Reflektion aufzurufen, müssen Sie alle Parameter übergeben, Standardwerte oder nicht.

Der folgende Code subtrahiert zwei Ganzzahlen und gibt die Differenz zurück. Es hat einen Standardparameter – b.

public class Util
{
	public int Subtract(int a, int b = 0)
	{
		return a - b;
	}
}
Code language: C# (cs)

Der folgende Code verwendet Reflektion, um diese Methode aufzurufen. Es wird nur einer der Parameter übergeben.

Util util = new Util();
int a = 1;
int b = 2;

var method = util.GetType().GetMethod("Subtract");
var parameters = new object[] { a };

var difference = method.Invoke(util, parameters);
Code language: C# (cs)

Util.Subtract() erwartet zwei Parameter – a und b. Es wird nur ein Parameter übergeben – a – daher löst dies TargetParameterCountException aus.

Aber warte, hat das nicht einen Standardparameter? Ja, aber Standardparameter funktionieren grundsätzlich nicht mit Reflektion. Sie müssen alle Parameter übergeben, auch wenn es sich um einen Standardparameter handelt.

Die Lösung ist einfach, übergeben Sie beide Parameter:

Util util = new Util();
int a = 1;
int b = 2;

var method = util.GetType().GetMethod("Subtract");
var parameters = new object[] { a, b };

var difference = method.Invoke(util, parameters);
Code language: C# (cs)

Reflektion zum Aufrufen einer Erweiterungsmethode verwenden

Erweiterungsmethoden sind nur statische Methoden. Die Methode wird in einer statischen Klasse definiert und von einem anderen Typ aufgerufen. Wie Sie vielleicht erraten haben, müssen Sie beim Aufrufen der Erweiterungsmethode mit Reflektion anders vorgehen, als Sie es normalerweise tun würden.

Angenommen, Sie haben die folgende Erweiterungsmethode:

public static class Util
{
	public static int Multiply(this int a, int b)
	{
		return a * b;
	}
}
Code language: C# (cs)

Ohne Reflexion würden Sie es so nennen:

a.Multiply(b);
Code language: C# (cs)

Mit Reflektion würden Sie es so nennen:

int a = 6;
int b = 3;

var method = typeof(Util).GetMethod("Multiply", BindingFlags.Static | BindingFlags.Public);
var parameters = new object[] { a, b };

var product = method.Invoke(null, parameters);
Code language: C# (cs)

Erstens, wenn Sie Reflektion zum Aufrufen einer statischen Methode verwenden, ist der erste Parameter von Invoke() null, da Sie ihn nicht auf einer Instanz aufrufen.

Zweitens müssen Sie, wie Sie in der hervorgehobenen Zeile sehen können, alle Parameter übergeben (genau wie bei Standardparametern). Andernfalls wird TargetParameterCountException ausgelöst.