Estoy tratando de crear una clase genérica que nueva crea una instancia del tipo genérico. En la siguiente manera:C# genéricos problema - revivir el tipo genérico con parámetros en el constructor
public class HomepageCarousel<T> : List<T>
where T: IHomepageCarouselItem, new()
{
private List<T> GetInitialCarouselData()
{
List<T> carouselItems = new List<T>();
if (jewellerHomepages != null)
{
foreach (PageData pageData in jewellerHomepages)
{
T item = new T(pageData); // this line wont compile
carouselItems.Add(item);
}
}
return carouselItems;
}
}
Pero me sale el siguiente error:
cannot provide arguments when creating an instance of a variable type
me encontré con la siguiente pregunta relacionada que está muy cerca de lo que necesito: Passing arguments to C# generic new() of templated type
Sin embargo, no puedo Utilicé la respuesta sugerida de Jared como soy llamando al método dentro de la clase genérica, no fuera de , por lo que no puedo especificar la clase concreta.
¿Hay alguna forma de evitar esto?
He intentado lo siguiente basado en la otra pregunta, pero no funciona, ya que no sé el tipo concreto de T a especifique. Como se le llama desde dentro de la clase genérica, no fuera:
public class HomepageCarousel<T> : List<T>
where T: IHomepageCarouselItem, new()
{
private List<T> LoadCarouselItems()
{
if (IsCarouselConfigued)
{
return GetConfiguredCarouselData();
}
// ****** I don't know the concrete class for the following line,
// so how can it be instansiated correctly?
return GetInitialCarouselData(l => new T(l));
}
private List<T> GetInitialCarouselData(Func<PageData, T> del)
{
List<T> carouselItems = new List<T>();
if (jewellerHomepages != null)
{
foreach (PageData pageData in jewellerHomepages)
{
T item = del(pageData);
carouselItems.Add(item);
}
}
return carouselItems;
}
}
******** EDIT: Añadido POSIBLES SOLUCIONES **
Así que he probado 2 soluciones posibles:
Primero es exactamente como se explica a continuación por Jon Skeet. Este definitivamente funciona pero significa tener un Lambda oscuro en el constructor . No me siento cómodo con esto, ya que significa que los usuarios de deben conocer la lambda correcta que se espera. Después de todo, podrían pasar un lambda que no tiene el tipo , pero hace algo completamente inesperado
En segundo lugar, seguí la ruta del método de fábrica; he añadido un método de creación de la interfaz común:
IJewellerHomepageCarouselItem Create(PageData pageData);
Entonces proporciona una implementación en cada clase concreta:
public IJewellerHomepageCarouselItem Create(PageData pageData)
{
return new JewellerHomepageCarouselItem(pageData, null);
}
Y utiliza una sintaxis de inicialización de dos pasos:
T carouselItem = new T();
T homepageMgmtCarouselItem = (T) carouselItem.Create(jewellerPage);
Would Me encantaría escuchar algunos comentarios sobre el mérito de cada uno de estos enfoques.
posible duplicado de [Pasar argumentos a C# genérico nuevo() del tipo de plantilla] (http://stackoverflow.com/questions/840261/passing -arguments-to-c-sharp-generic-new-of-templated-type) – nawfal