Domanda

Di 'Ho un metodo generico con più vincoli di tipo, questo questo:

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

Ora .... come posso, utilizzando la riflessione, creare qualcosa posso inviare lì dentro?

Se era solo un vincolo so che posso fare in questo modo:

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

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

Ma, non si può davvero lanciare a più interfacce ... come diavolo posso risolvere questo problema? Si potrebbe dire che sono praticamente perso qui ora: P

Titolo ottenuto sorta di lungo e complesso come io non ero sicuro di cosa chiamare questo, si prega di migliorare se è possibile

È stato utile?

Soluzione

Per aggiungere a Reed e Loren di risposte su come trovare i tipi adatti, ricordiamo che ancora non sarà in grado di chiamare DoSomethingAwesome per fusione, perché come hai trovato, il compilatore non fornisce un modo per lanciare l'oggetto istanziato per interfacce multiple. Sono disponibili due opzioni:

  1. Crea una nuova interfaccia IAwesomeComparableThing che deriva da IThing, IAwesome e IComparable , avere il vostro tipi implementano questo, e gettati a che.

  2. Invoke DoSomethingAwesome attraverso riflessione. Per fare questo, si vuole necessario per ottenere il MethodInfo per il DoSomethingAwesome metodo generico, quindi chiamare MethodInfo.MakeGenericMethod con il tipo che implementa tutti e tre interfacce.

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

Altri suggerimenti

Sto indovinando c'è qualche ragione per cui non si può fare

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

È necessario un tipo che è assegnabile da tutti i vincoli. I primi due sono facili, ma il terzo è un po 'più complicato:

// 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) );
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top