Modifier:
Bien sûr, mon vrai code ne ressemble pas exactement à ça. J'ai essayé d'écrire du code semi-pseudo pour le rendre plus clair sur ce que je voulais faire.
On dirait que ça a tout gâché.
Donc, ce que je voudrais réellement faire est la suivante:
Method<Interface1>();
Method<Interface2>();
Method<Interface3>();
...
Eh bien ... je pensais que je pourrais peut-être en faire une boucle en utilisant la réflexion. La question est donc: comment puis-je le faire. J'ai très connaissance superficielle de la réflexion. Donc, des exemples de code seraient formidables.
Le scénario ressemble à ceci:
public void Method<T>() where T : class
{}
public void AnotherMethod()
{
Assembly assembly = Assembly.GetExecutingAssembly();
var interfaces = from i in Assembly.GetTypes()
where i.Namespace == "MyNamespace.Interface" // only interfaces stored here
select i;
foreach(var i in interfaces)
{
Method<i>(); // Get compile error here!
}
Message original:
Salut!
J'essaie de parcourir toutes les interfaces d'un espace de noms et de les envoyer en tant qu'arguments à une méthode générique comme celle-ci:
public void Method<T>() where T : class
{}
public void AnotherMethod()
{
Assembly assembly = Assembly.GetExecutingAssembly();
var interfaces = from i in Assembly.GetTypes()
where i.Namespace == "MyNamespace.Interface" // only interfaces stored here
select i;
foreach(var interface in interfaces)
{
Method<interface>(); // Get compile error here!
}
}
L'erreur que j'obtiens est "Nom de type attendu, mais nom de variable local trouvé". Si j'essaye
...
foreach(var interface in interfaces)
{
Method<interface.MakeGenericType()>(); // Still get compile error here!
}
}
J'obtiens "Impossible d'appliquer l'opérateur '<' aux opérandes de type 'groupe de méthodes' et 'System.Type'". Avez-vous une idée sur la façon de contourner ce problème?
EDIT: OK, le temps d'un programme court mais complet. La réponse de base est comme avant:
Voici un exemple de code. Notez que j'ai changé l'expression de requête en notation par points: il n'y a aucun intérêt à utiliser une expression de requête si vous venez de recevoir une clause where.
using System;
using System.Linq;
using System.Reflection;
namespace Interfaces
{
interface IFoo {}
interface IBar {}
interface IBaz {}
}
public class Test
{
public static void CallMe<T>()
{
Console.WriteLine("typeof(T): {0}", typeof(T));
}
static void Main()
{
MethodInfo method = typeof(Test).GetMethod("CallMe");
var types = typeof(Test).Assembly.GetTypes()
.Where(t => t.Namespace == "Interfaces");
foreach (Type type in types)
{
MethodInfo genericMethod = method.MakeGenericMethod(type);
genericMethod.Invoke(null, null); // No target, no arguments
}
}
}
réponse originale
Laissons de côté les problèmes évidents d'appeler une variable "interface" pour commencer.
Vous devez l'appeler par réflexion. Le but des génériques est de mettre plus de vérification de type à la compilation . Vous ne savez pas quel est le type au moment de la compilation - vous devez donc utiliser des génériques.
Obtenez la méthode générique et appelez-la MakeGenericMethod, puis appelez-la.
Votre type d'interface est-il réellement générique? Je demande parce que vous appelez MakeGenericType dessus, mais ne transmettez aucun argument de type ... Essayez-vous d'appeler
Method<MyNamespace.Interface<string>>(); // (Or whatever instead of string)
ou
Method<MyNamespace.Interface>();
Si c'est le dernier cas, vous avez uniquement besoin d'un appel à MakeGenericMethod - et non à MakeGenericType.