ich Ironpython bin mit und ich weiß, wie Methoden aus meiner Klasse der Skripts Umfang aussetzen:Ironpython - Verborgene Methoden Reflexion mit
m_scope.SetVariable("log", new Action<string>(Log));
public void Log(string a)
{
Console.WriteLine(a);
}
Doch anstatt Aufruf SetVariable
jedes Mal wenn ich will, den Prozess beschleunigen mit Reflexion. Also, habe ich ein Attribut ScriptMethodAttribute
genannt:
public sealed class ScriptMethodAttribute : Attribute
{
public string Name { get; private set; }
public ScriptMethodAttribute(string name)
{
Name = name;
}
}
Auf diese Weise kann ich Methoden in meiner Klasse definieren für das Skript zu verwenden, etwa so:
[ScriptMethod("log")]
public void Log(string a)
{
Console.WriteLine(a);
}
Jetzt möchte ich SetVariable auf jeden anrufen Methode, die dieses Attribut verwendet, um den Prozess zu beschleunigen. Das scheint jedoch nicht zu funktionieren.
Dies ist eine Hilfsmethode, die eine Liste von Tuple<ScriptMethodAttribute, MethodInfo
zurückgibt. in meinem Skript Klassenkonstruktors
public static IEnumerable<Tuple<TAttribute, MethodInfo>> FindMethodsByAttribute<TAttribute>()
where TAttribute : Attribute
{
return (from method in AppDomain.CurrentDomain.GetAssemblies()
.Where(assembly => !assembly.GlobalAssemblyCache)
.SelectMany(assembly => assembly.GetTypes())
.SelectMany(type => type.GetMethods())
let attribute = Attribute.GetCustomAttribute(method, typeof(TAttribute), false) as TAttribute
where attribute != null
select new Tuple<TAttribute, MethodInfo>(attribute, method));
}
Dieses befindet:
foreach (var a in Reflector.FindMethodsByAttribute<ScriptMethodAttribute>())
{
Action action = (Action)Delegate.CreateDelegate(typeof(Action), this, a.Item2);
m_scope.SetVariable(a.Item1.Name, action);
}
Ich erhalte die folgende Ausnahme:
System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
Ich vermute, es ist, weil ich die erforderliche enthalten haben Typen im Action-Konstruktor, aber ich weiß nicht, wie man sie aus der Klasse MethodInfo
bekommt.
Und was, wenn meine Methode überhaupt keine Parameter benötigt? Wie würde ich dann den Typ bekommen? Gibt es auch eine Möglichkeit, den Typ basierend auf der Anzahl der Parameter zu erhalten, so dass ich diese auf jede gewünschte Anzahl von Parametern erweitern kann und mich nicht auf einen beschränken muss? –
Ok, ich verstehe. Darüber habe ich nachgedacht. Definitiv nicht elegant, aber sehr schlau. –
Wenn ich versuche, eine Aktion hinzuzufügen, die keine Parameter akzeptiert, erhalte ich eine InvalidOperatioNException, die besagt: System.Action ist keine GenericTypeDefinition. MakeGenericType kann nur für einen Typ aufgerufen werden, für den Type.IsGenericTypeDefinition True ist. –