Contexto: .NET 3.5, VS2008. No estoy seguro del título de esta pregunta, así que no dude en comentar sobre el título :-)¿Cómo puedo escribir una clase de contenedor genérica que implemente una interfaz dada en C#?
Aquí está el escenario: Tengo varias clases, digamos Foo and Bar, todas ellas implementan la siguiente interfaz :
public interface IStartable
{
void Start();
void Stop();
}
Y ahora me gustaría tener una clase de contenedor, que recibe un IEnumerable <IStartable> como un argumento en su constructor. Esta clase, a su vez, también debe implementar la interfaz IStartable:
public class StartableGroup : IStartable // this is the container class
{
private readonly IEnumerable<IStartable> startables;
public StartableGroup(IEnumerable<IStartable> startables)
{
this.startables = startables;
}
public void Start()
{
foreach (var startable in startables)
{
startable.Start();
}
}
public void Stop()
{
foreach (var startable in startables)
{
startable.Stop();
}
}
}
Así que mi pregunta es: ¿cómo puedo hacerlo sin tener que escribir manualmente el código, y sin generación de código? En otras palabras, me gustaría tener algo así como el siguiente.
var arr = new IStartable[] { new Foo(), new Bar("wow") };
var mygroup = GroupGenerator<IStartable>.Create(arr);
mygroup.Start(); // --> calls Foo's Start and Bar's Start
Restricciones:
- Sin generación de código (es decir, ningún código textual real en tiempo de compilación)
- La interfaz tiene sólo métodos vacíos, con o sin argumentos
Motivo:
- Tengo una aplicación bastante grande, con muchos complementos de varias interfaces. escribir manualmente una clase de "contenedor de grupos" para cada interfaz "sobrecarga" del proyecto con las clases
- manualmente escribir el código es propenso a errores
- Cualquier adición o actualización de firmas a la interfaz IStartable dará lugar a cambios (manual) en el " grupo de contenedores" clase
- Aprender
entiendo que tengo que utilizar la reflexión aquí, pero yo prefiero usar un marco sólido (como el castillo de DynamicProxy o RunSharp) para hacer el cableado para mí.
¿Alguna idea?
¿Entonces * no * desea tener una clase StartableGroup? ¿Qué pasa con eso? – Noldorin
¿Puedo preguntar: ¿por qué? ¿Cuál es el problema que esto necesita resolver? (Esto puede afectar la respuesta ...). –
@Noldorin, @Marc Gravell, motivación añadida a la pregunta original. –