Passaggio di argomenti a C# generico new() di tipo basato su modelli

Passaggio di argomenti a C# generico new() di tipo basato su modelli

Per creare un'istanza di un tipo generico in una funzione è necessario vincolarla con il flag "nuovo".

public static string GetAllItems<T>(...) where T : new()

Tuttavia, funzionerà solo quando si desidera chiamare il costruttore che non ha parametri. Non è il caso qui. Dovrai invece fornire un altro parametro che consenta la creazione di oggetti basati su parametri. La più semplice è una funzione.

public static string GetAllItems<T>(..., Func<ListItem,T> del) {
  ...
  List<T> tabListItems = new List<T>();
  foreach (ListItem listItem in listCollection) 
  {
    tabListItems.Add(del(listItem));
  }
  ...
}

Puoi quindi chiamarlo così

GetAllItems<Foo>(..., l => new Foo(l));

in .Net 3.5 e dopo potresti usare la classe attivatore:

(T)Activator.CreateInstance(typeof(T), args)

Dal momento che nessuno si è preso la briga di pubblicare la risposta "Riflessione" (che personalmente ritengo sia la risposta migliore), ecco qui:

public static string GetAllItems<T>(...) where T : new()
{
   ...
   List<T> tabListItems = new List<T>();
   foreach (ListItem listItem in listCollection) 
   {
       Type classType = typeof(T);
       ConstructorInfo classConstructor = classType.GetConstructor(new Type[] { listItem.GetType() });
       T classInstance = (T)classConstructor.Invoke(new object[] { listItem });

       tabListItems.Add(classInstance);
   } 
   ...
}

Modifica:questa risposta è deprecata a causa di Activator.CreateInstance di .NET 3.5, tuttavia è ancora utile nelle versioni precedenti di .NET.