Pointeurs de fonction en C#
Je suppose que, à certains égards (ou les deux) Delegate
ou MethodInfo
qualifier pour ce titre. Toutefois, ni fournir les syntaxiques de la gentillesse que je suis à la recherche pour. Donc, en résumé, Est-il une manière que je peux écrire ce qui suit:
FunctionPointer foo = //whatever, create the function pointer using mechanisms
foo();
Je ne peux pas utiliser un solide délégué (c'est à dire, à l'aide de la delegate
mot clé de déclarer un type délégué), car il n'y a aucun moyen de savoir jusqu'à l'exécution exacte de la liste des paramètres. Pour référence, voici ce que j'ai pensé en LINQPad actuellement, où B
sera (pour la plupart) de l'utilisateur code généré, et il en sera de Main
, et donc pour la finesse de mes utilisateurs, je suis en train de supprimer la .Call
:
void Main()
{
A foo = new B();
foo["SomeFuntion"].Call();
}
//Define other methods and classes here
interface IFunction {
void Call();
void Call(params object[] parameters);
}
class A {
private class Function : IFunction {
private MethodInfo _mi;
private A _this;
public Function(A @this, MethodInfo mi) {
_mi = mi;
_this = @this;
}
public void Call() { Call(null); }
public void Call(params object[] parameters) {
_mi.Invoke(_this, parameters);
}
}
Dictionary<string, MethodInfo> functions = new Dictionary<string, MethodInfo>();
public A() {
List<MethodInfo> ml = new List<MethodInfo>(this.GetType().GetMethods());
foreach (MethodInfo mi in typeof(Object).GetMethods())
{
for (int i = 0; i < ml.Count; i++)
{
if (ml[i].Name == mi.Name)
ml.RemoveAt(i);
}
}
foreach (MethodInfo mi in ml)
{
functions[mi.Name] = mi;
}
}
public IFunction this[string function] {
get {
if (!functions.ContainsKey(function))
throw new ArgumentException();
return new Function(this, functions[function]);
}
}
}
sealed class B : A {
public void SomeFuntion() {
Console.WriteLine("SomeFunction called.");
}
}
OriginalL'auteur Matthew Scharley | 2009-07-26
Vous devez vous connecter pour publier un commentaire.
Vous dites que vous voulez garder le nombre et le type de paramètres ouverte, mais vous pouvez le faire avec un delgate:
C'est exactement la même chose que vous avez actuellement. Essayez ceci:
Vous pouvez penser à un exemple de la méthode de délégué comme très semblable à votre
Function
classe: un objet d'uneMethodInfo
. Donc il n'y a pas besoin de le réécrire.Aussi des pointeurs de fonction en C et C++ ne sont pas plus près de ce dont vous avez besoin: ils ne peuvent pas être lié à une instance d'objet et fonction, et aussi, ils sont statiquement typé, pas typées dynamiquement.
Si vous voulez "wrap" toute autre méthode dans un DynamicFunc délégué, essayez ceci:
et puis:
Remarque que je suis en utilisant une méthode statique
Foo
donc je passenull
pour l'exemple, mais si c'était une méthode d'instance, je serais de passage de l'objet à lier.Program
se trouve être la classe de mes méthodes statiques sont définis dans.Bien sûr, si vous passez les mauvais types d'argument, puis vous obtenez des erreurs lors de l'exécution. Je serais probablement chercher un moyen pour la conception de votre programme de sorte que, comme beaucoup de type de données saisies au moment de la compilation que possible.
C'est beaucoup plus complexe... accrocher.
Ok, peut-être pas aussi complexe... voir la mise à jour.
Le temps de compilation pour le
B
classe sera d'exécution, comme je l'ai dit, il est généré par l'utilisateur, donc, malheureusement, toutes les erreurs, il y aura manipulé par eux (et il y a de bonnes dispositions, les rapports d'erreurs, etc, pour le faire).Juste assez pour paraphraser Einstein, un programme doit être aussi statiquement typé que possible, mais pas statiquement typé-er.
OriginalL'auteur Daniel Earwicker
Voici un autre morceau de code que vous pourriez utiliser; la Réflexion est plutôt lent, donc, si vous attendez votre Dynamique des appels de fonction pour être appelé fréquemment, vous ne voulez pas de méthode.Invoquer à l'intérieur de la délégué:
Et vous pouvez l'utiliser comme ceci:
Ce sera un peu plus rapide; chaque appel dynamique verra la participation de 1 typecheck par param, 2 déléguer des appels, et un tableau de construction en raison de la params de style en passant.
Par curiosité j'ai programmé cette technique (avec deux paramètres) contre la mienne, et a constaté que ma méthode a une surcharge de trois et demi de millionièmes de seconde par appel. Donc je pense que la surcharge est peu probable d'être un problème dans une application réelle; tout dépend de ce genre de choses seront vos utilisateurs à faire dans leurs fonctions.
OriginalL'auteur Eamon Nerbonne