Créer une instance de classe générique avec un paramètre de type générique dynamic

J’ai besoin de créer une instance d’une classe générique comme ceci:

Type T = Type.GetType(className).GetMethod(functionName).ReturnType; var comparer = new MyComparer(); // ERROR: "The type or namespace name 'T' could not be found" 

J’ai trouvé cette réponse où cela n’est possible qu’avec la reflection. Mais en utilisant la reflection, je reçois un object que je dois convertir en mon type générique. J’ai essayé comme ça

  Type myGeneric = typeof(MyComparer); Type constructedClass = myGeneric.MakeGenericType(); object created = Activator.CreateInstance(constructedClass); var comparer = (T)Convert.ChangeType(created, T);// ERROR: "The type or namespace name 'T' could not be found" 

mais obtenez la même erreur. Comment le résoudre?

Voici un exemple complet:

  public static bool Test(ssortingng className, ssortingng functionName, object[] parameters, object correctResult) { var method = Type.GetType(className).GetMethod(functionName); Type T = method.ReturnType; var myResult = method.Invoke(null, parameters); dynamic myResultAsT = Convert.ChangeType(myResult, T); dynamic correctResultAsT = Convert.ChangeType(correctResult, T); var comparer = new MyComparer(); // Problem is here!!! return comparer.Equals(myResultAsT, correctResultAsT); } 

L’idée est de faire un test unitaire qui appellera une fonction avec des parameters et comparera son résultat avec le résultat correct. Mais comme j’ai besoin d’un comparateur personnalisé, MyComparer que je ne peux pas utiliser à cause d’une erreur du compilateur.

 public class MyComparer : IEqualityComparer { public bool Equals(T x, T y){/* some implementation*/} } 

J’ai trouvé une solution très simple au problème. Il n’est pas nécessaire de convertir un object en un type spécifique T , il suffit d’utiliser dynamic mot clé dynamic au lieu de

  Type myGeneric = typeof(MyComparer<>); Type constructedClass = myGeneric.MakeGenericType(T); object created = Activator.CreateInstance(constructedClass); dynamic comparer = created; // No need to cast created object to T 

et puis je peux utiliser normalement Composer pour appeler ses méthodes comme:

  return comparer.Equals(myResultAsT, correctResultAsT); 

Selon les commentaires de LueTm , il est probablement possible d’utiliser à nouveau la reflection et les méthodes de comparaison d’ appels, mais cette solution semble beaucoup plus simple.

On dirait que tu y es presque:

 // t is a variable, so make it lowercase. This is where some of the confusion comes from Type t = Type.GetType(className).GetMethod(functionName).ReturnType; Type myGeneric = typeof(IEqualityComparer<>); // You need to provide the generic type to make it generic with // You want IEqualityComparer, so: Type constructedClass = myGeneric.MakeGenericType(t); // Now create the object object created = Activator.CreateInstance(constructedClass); // This is sortingcky without more context... // You could try this, but to tell you more I would need to know where you use // the comparer instance. Are you using it in a LINQ query, or in a Sort()? // If so just cast it to a IEqualityComparer, and // make YourType whaterver you need it to be in the list or the query... var comparer = (IEqualityComparer)created;