Pergunta

dizer que tenho um método genérico com várias restrições de tipo, este este:

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

Agora .... como posso, usando a reflexão, criar algo que eu possa enviar para lá?

Se fosse apenas uma restrição eu sei que posso fazê-lo como este:

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

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

Mas, não pode realmente convertido para múltiplas interfaces ... como na terra eu posso resolver isso? Você poderia dizer que eu estou praticamente perdido aqui agora: P

Título tenho tipo de longo e complexo como eu não tinha certeza do que chamar a isto, por favor melhorar se você pode

Foi útil?

Solução

Para adicionar respostas de Reed e Loren sobre encontrar tipos adequados, nota que você ainda não será capaz de chamar DoSomethingAwesome por vazamento, porque como você ter encontrado, o compilador não fornece uma maneira de converter o objeto instanciado para várias interfaces. Você tem duas opções:

  1. Criar uma nova interface IAwesomeComparableThing que deriva de IThing, e IAwesome IComparable , ter o seu tipos implementar isso, e convertido para isso.

  2. Invoke DoSomethingAwesome através reflexão. Para fazer isso, você vai precisa para obter o MethodInfo para o método genérico DoSomethingAwesome, então ligue MethodInfo.MakeGenericMethod com seu tipo que implementa todas três interfaces.

Exemplo 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 });

Outras dicas

Eu estou supondo que há algum motivo você não pode fazer

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

Você precisa de um tipo que é atribuível a partir de todas as suas limitações. Os dois primeiros são fáceis, mas o terceiro é um pouco mais complicado:

// 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) );
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top