Il semble que la réponse soit "non".
Lorsque vous appelez Transform
directement, vous devez spécifier un paramètre de type:
int i = Transform<int>("");
donc hypothétiquement, si vous pouviez passer une incomplètement construit fonction générique comme vous voulez, vous aurez besoin de préciser la paramètres de type ainsi:
void GeneralizedFunction(string aStringA, string aStringB, Func<string, T> aAction)
{
A result1 = aAction<A>(aStringA);
B result2 = aAction<B>(aStringB);
// Do something with A and B here
}
il me semble que vous pourriez hypothétiquement faire, si C# a une syntaxe comme ça.
Mais quel est le cas d'utilisation? Mis à part transformer les chaînes à la valeur par défaut d'un type arbitraire, je ne vois pas beaucoup d'utilité pour cela. Comment pourriez-vous définir une fonction qui fournirait un résultat significatif dans l'un ou l'autre de deux types différents en utilisant la même série d'instructions?
EDIT
Une analyse des raisons pour lesquelles il est impossible:
Lorsque vous utilisez une expression lambda dans votre code, il est compilé dans soit un délégué ou un arbre d'expression; dans ce cas, c'est un délégué. Vous ne pouvez pas avoir une instance d'un type générique "ouvert"; en d'autres termes, pour créer un objet à partir d'un type générique, tous les paramètres de type doivent être spécifiés.En d'autres termes, il n'y a aucun moyen d'avoir une instance d'un délégué sans fournir d'arguments pour tous ses paramètres de type. L'une des fonctionnalités utiles du compilateur C# est la conversion implicite de groupes de méthodes, où le nom d'une méthode (un "groupe de méthodes") peut être implicitement converti en un type délégué représentant l'une des surcharges de cette méthode. De même, le compilateur convertit implicitement une expression lambda en un type délégué. Dans les deux cas, le compilateur émet du code pour créer une instance du type délégué (dans ce cas, pour le passer à la fonction). Mais l'instance de ce type de délégué doit toujours avoir un argument type pour chacun de ses paramètres de type.
Pour passer la fonction générique en fonction générique, il semble, le compilateur devrait être en mesure de passer le groupe de méthode ou l'expression lambda la méthode sans conversion, de sorte que le aAction
paramètre aurait en quelque sorte un type de "groupe de méthodes" ou "expression lambda". Ensuite, la conversion implicite en un type délégué peut se produire sur les sites d'appel A result1 = aAction<A>(aStringA);
et B result2 = aAction<B>(aStringB);
. Bien sûr, à ce stade, nous sommes bien dans l'univers des contrefactuels et des hypothétiques.
La solution que je suis venu avec au cours du déjeuner était ce, en supposant une fonction Deserialize<T>
qui prend une chaîne contenant des données sérialisés et retourne un objet de type T
:
void GeneralizedFunction<T>(string aStringA, string aStringB, Func<T, string> stringGetter)
{
A result1 = Deserialize<A>(stringGetter(aStringA));
B result2 = Deserialize<B>(stringGetter(aStringB));
}
void Example(string serializedA, string serializedB, string pathToA, string pathToB, FileInfo a, FileInfo b)
{
GeneralizedFunction(serializedA, serializedB, s => s);
GeneralizedFunction(pathToA, pathToB, File.ReadAllText);
GeneralizedFunction(a, b, fi => File.ReadAllText(fi.FullName));
}
Qu'est-ce tu veux faire exactement? puisque vous ne voulez pas donner à GeneralizedFunction aucune information de type concernant la fonction Transform, pourquoi ne pas accepter une nouvelle fonction en prenant une chaîne et en retournant un objet (dont tout le monde sait que tout le monde est *) – Polity
A et B "placeholder cache la partie problématique. A et B vont-ils toujours être des types particuliers? Alors vous n'avez pas besoin de génériques. Sont-ils arbitraires (peut-être avec des contraintes)? Ensuite, GeneralizedFunction doit être générique en eux. – AakashM
A et B sont des types concrets, mais Transform est une fonction générique. – Max