Frage

sagen, ich habe eine generische Methode mit mehreren Typeinschränkungen, dies folgt aus:

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

Nun .... wie kann ich, mit Reflexion, schaffen etwas, das ich dort senden kann?

Wenn es nur eine Einschränkung war weiß ich, dass ich es wie folgt tun:

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

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

Aber kann nicht wirklich auf mehrere Schnittstellen werfen ... wie auf der Erde kann ich dieses Problem lösen? Man könnte sagen, ich bin ziemlich viel hier jetzt verloren: P

Titel bekam Art von lang und komplex, da ich nicht sicher war, was diese zu nennen, verbessern Sie, wenn Sie können

War es hilfreich?

Lösung

Um zu Reed und Lorens Antworten zu finden, geeignete Typen, Notiz hinzufügen, dass Sie nach wie vor nicht in der Lage sein DoSomethingAwesome durch Gießen zu nennen, weil, wie Sie gefunden haben, wird der Compiler nicht bietet eine Möglichkeit, das instanzierte Objekt zu gieße mehrere Schnittstellen. Sie haben zwei Möglichkeiten:

  1. Erstellen Sie eine neue Schnittstelle IAwesomeComparableThing denen ergibt sich aus IThing, IAwesome und IComparable , haben Sie Ihren Typen implementieren, dass und zu gieße das.

  2. Invoke DoSomethingAwesome durch Reflexion. Um dies zu tun, werden Sie müssen die Method für das bekommen DoSomethingAwesome generische Methode, Dann ruf an MethodInfo.MakeGenericMethod mit Ihre Art, dass alle drei Geräte Schnittstellen.

Beispiel (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 });

Andere Tipps

Ich vermute, es gibt einigen Grund, warum Sie nicht tun können,

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

Sie benötigen einen Typ, der von allen Ihren Einschränkungen zuweisbare ist. Die ersten beiden sind einfach, aber der dritte ist ein bisschen schwieriger:

// 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) );
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top