Estoy buscando formas de mejorar la coherencia, brevedad y legibilidad de algunos códigos en la aplicación en la que estoy trabajando. El código que empieza parecía algo como esto:C# Método de extensión en tipo con argumento de tipo genérico
context.GetGraphType<Bar>().Subscribe<Fizz>(
(instance, evt) => e.Execute((Bar)instance.Instance)
);
Hay una serie de líneas casi idénticas de código como el anterior. Yo quería volver a escribir a ser algo como esto:
typeof(Bar).SubscribeTo<Fizz>(context);
Por un lado, esto permitiría que tome ventaja de formalizar lo que ya se había convertido en una convención informal. Además, esperaba que ahora dijera algo así como "el bar se suscribe al evento de fizz en el contexto dado", en lugar de "el contexto tiene el tipo de barra y se suscribe a fizz y luego hace algunas cosas". Creo que el flujo es mejor, y el compañero de trabajo al que pregunté estuvo de acuerdo.
Comencé a implementar esto como un método de extensión. Para lograr lo anterior, quería hacer uso de una clase base genérica abstracta para el tipo de evento, por lo que Fizz
sería Event<T>
. Esto significaría que el argumento de tipo genérico para el método de extensión tendría que estar restringido para ser del tipo que se solicita el método de extensión. Entonces, para el ejemplo anterior, Fizz
debería ser del tipo Event<Bar>
.
¿Esto es posible? Mientras tanto, fui con una solución alternativa, pero todavía tengo curiosidad de saber si puede lograrse. Otras sugerencias son bienvenidas también.
Gracias!
Edición n. ° 1: Para que quede claro, me doy cuenta de que podría usar un parámetro de tipo adicional, pero estoy buscando la forma de evitarlo si es posible.
Edit # 2: Creo que voy a ir con una ligera variación de la respuesta aceptada, ya que no coincide al 100% con mi escenario. La conclusión es que se puede usar una clase estática genérica en lugar de un método de extensión de Tipo para lograr mi objetivo. Gracias dss539!
código de actualización (puede haber errores tipográficos ya que estoy haciendo esto sobre la marcha):
public class Bar { }
public class Event<TSubscriber>
{
public abstract void Execute(TSubscriber source);
}
public class Fizz : Event<Bar>
{
public override void Execute(Bar bar)
{
// respond to event
}
}
public class Context { }
public static class ForType<TSubscriber>
{
public static void SubscribeTo<TEvent>(Context context)
where TEvent : Event<TSubscriber>
{
context.GetType<TSubscriber>().Subscribe<TEvent>(
(evt, args) => evt.Execute((TSubscriber)args.Source));
}
}
public static void Run()
{
ForType<Bar>.SubscribeTo<Fizz>(context);
}
No entiendo muy bien su pregunta. ¿Cómo se ve la firma de su método actual? 'Suscribir (este Tipo tipo, Acción )'? Si muestra lo que tiene (o su equivalente), eso puede ayudar a explicar. –
dss539
Creo que tuve un problema de diseño similar hace un tiempo. Buena suerte :) – leppie
@ dss539 Sería más como Suscribir (este Tipo de tipo, Contexto ctx). El problema es que no hay forma (que yo sepa) de restringir que T sea del tipo Evento . –