Pregunta

Decir que tengo un método genérico con múltiples restricciones de tipo, esta esto:

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

Ahora .... ¿cómo puedo, utilizando la reflexión, crear algo que pueda enviar allí?

Si era sólo una limitación sé que puedo hacerlo de esta manera:

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

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

Pero, en realidad no pueden transmitir contenido a múltiples interfaces ... ¿cómo diablos puedo solucionar esto? Se podría decir que estoy bastante perdido aquí ahora: P

Título consiguió especie de largo y complejo ya que no estaba seguro de cómo llamar esto, por favor mejorar si es posible

¿Fue útil?

Solución

Para añadir a las respuestas Reed y de Loren sobre la búsqueda de tipos adecuados, tenga en cuenta que todavía no será capaz de llamar DoSomethingAwesome por fundición, porque a medida que haya encontrado, el compilador no proporciona una manera de convertir el objeto instanciado a múltiples interfaces. Tiene dos opciones:

  1. Crea una nueva interfaz IAwesomeComparableThing cuales deriva de iThing, y IAwesome IComparable , haga que su tipos implementar eso, y echaron a que.

  2. Invoke DoSomethingAwesome través reflexión. Para ello, se quiere que obtener el MethodInfo para el DoSomethingAwesome método genérico, luego llame MethodInfo.MakeGenericMethod con su tipo que implementa los tres interfaces.

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

Otros consejos

supongo que hay alguna razón no se puede hacer

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

Es necesario un tipo que es asignable a todas sus limitaciones. Los dos primeros son fáciles, pero el tercero es un poco más 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top