Możesz zobaczyć, co próbuję (ale bezskutecznie) zrobić z następującym kodem:
protected T GetObject()
{
return new T();
}
Każda pomoc byłaby bardzo mile widziana.
EDYTOWAĆ:
Kontekst był następujący. Bawiłem się niestandardową klasą kontrolera, z której miały pochodzić wszystkie kontrolery, przy użyciu standardowych metod. W kontekście musiałem więc stworzyć nową instancję obiektu typu kontroler. Więc w czasie pisania było to coś takiego:
public class GenericController<T> : Controller
{
...
protected T GetObject()
{
return (T)Activator.CreateInstance(ObjectType);
}
public ActionResult Create()
{
var obj = GetObject()
return View(obj);
}
Postanowiłem więc, że tu najłatwiej będzie nam zadbać o refleksję. Zgadzam się, że z pewnością biorąc pod uwagę początkowe stwierdzenie pytania, najwłaściwszą odpowiedzią do oznaczenia jako poprawną była ta, w której zastosowano nowe () ograniczenie. Naprawiłem to.
Odpowiedzi:
Spójrz na nowe ograniczenie
T
mogłaby być klasą, która nie ma domyślnego konstruktora: w tym przypadkunew T()
byłaby to nieprawidłowa instrukcja.new()
Ograniczenie mówi, żeT
musi mieć konstruktora domyślnego, co czyninew T()
prawa.Możesz zastosować to samo ograniczenie do metody ogólnej:
Jeśli potrzebujesz przekazać parametry:
źródło
Dlaczego nikt nie zasugerował
Activator.CreateInstance
?http://msdn.microsoft.com/en-us/library/wccyzw83.aspx
źródło
Innym sposobem jest użycie refleksji:
źródło
Aby zakończyć, najlepszym rozwiązaniem jest często wymaganie argumentu funkcji fabrycznej:
i nazwij to mniej więcej tak:
W razie potrzeby można tego użyć, aby wymagać lub skorzystać z dostępnych parametrów.
źródło
Nowy ograniczeniem jest w porządku, ale jeśli trzeba T jest typ wartości też użyć tego:
źródło
Ponieważ jest oznaczony jako C # 4. Z otwartym środowiskiem źródłowym ImpromptuIntereface użyje dlr do wywołania konstruktora, jest to znacznie szybsze niż Activator, gdy konstruktor ma argumenty, i pomijalnie wolniejsze, gdy ich nie ma. Jednak główną zaletą jest to, że poprawnie obsłuży konstruktory z opcjonalnymi parametrami C # 4.0, czego nie zrobi Activator.
źródło
Aby to uzyskać, wypróbowałem następujący kod:
źródło