Question

Dire que j'ai une méthode générique avec de multiples contraintes de type, ce ceci:

public static void DoSomethingAwesome<T>(T thing)
    where T : IThing, IAwesome, IComparable<T>
{
    ...
}

.... comment puis-je, en utilisant la réflexion, créer quelque chose que je peux envoyer là-dedans?

Si c'était une seule contrainte, je sais que je peux le faire comme ceci:

var types = assembly
      .GetTypes()
      .Where(typeof (IThing).IsAssignableFrom)

foreach(var t in types)
    DoSomethingAwesome((IThing) Activator.CreateInstance(t));

Mais, ne peut pas vraiment jeter à plusieurs interfaces ... comment diable puis-je résoudre ce problème? Vous pourriez dire que je suis à peu près perdu ici maintenant: P

Titre obtenu sorte de long et complexe que je ne savais pas comment appeler cela, s'il vous plaît améliorer si vous le pouvez

Était-ce utile?

La solution

Pour ajouter à Reed et les réponses de Loren sur la recherche de types appropriés, notez que vous serez toujours pas en mesure d'appeler DoSomethingAwesome par coulée, parce que vous avez trouvé, le compilateur ne fournit pas un moyen de jeter l'objet instancié à plusieurs interfaces. Vous avez deux options:

  1. Créer une nouvelle interface IAwesomeComparableThing qui dérive de IThing, et IAwesome IComparable , demandez à votre types qui mettent en œuvre, et à jeter que.

  2. Invoke DoSomethingAwesome par réflexion. Pour ce faire, vous besoin d'obtenir le MethodInfo pour la DoSomethingAwesome méthode générique, puis appelez MethodInfo.MakeGenericMethod avec le type qui implémente les trois interfaces.

Exemple de (2):

Type type = sometype; // For example found using reeds method
MethodInfo mgeneric = typeof(Awesomeiser).GetMethod("DoSomethingAwesome");
MethodInfo mspecific = mgeneric.MakeGenericMethod(new [] { type });
mspecific.Invoke(null, new [] { type });

Autres conseils

Je suppose qu'il ya une raison quelconque vous ne pouvez pas faire

var types = assembly
.GetTypes()
.Where(typeof (IThing).IsAssignableFrom && typeof (IAwesome).IsAssignableFrom))

Vous avez besoin d'un type qui est assignable de toutes vos contraintes. Les deux premiers sont faciles, mais le troisième est un peu plus compliqué:

// Using
static bool IsIComparable(Type thing)
    {
        foreach (Type interfaceType in thing.GetInterfaces())
        {
            if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof (IComparable<>))
            {
                Type[] arguments = interfaceType.GetGenericArguments();
                if (arguments.Length == 1)
                {
                    if (arguments[0] == thing)
                        return true;
                }
            }
        }
        return false;
    }


// This returns an enumerable of compatible types:
var types = assembly.GetTypes().Where( t => 
   typeof(IThing).IsAssignableFrom(t) &&
   typeof(IAwesome).IsAssignableFrom(t) &&
   IsIComparable(t) );
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top