Sie können sehen, was ich mit dem folgenden Code zu tun versuche (aber nicht tue):
protected T GetObject()
{
return new T();
}
Jede Hilfe wäre sehr dankbar.
BEARBEITEN:
Der Kontext war wie folgt. Ich spielte mit einer benutzerdefinierten Controller-Klasse, von der alle Controller mit standardisierten Methoden abgeleitet werden konnten. Daher musste ich im Kontext eine neue Instanz des Objekts des Controllertyps erstellen. Zum Zeitpunkt des Schreibens war es so etwas wie:
public class GenericController<T> : Controller
{
...
protected T GetObject()
{
return (T)Activator.CreateInstance(ObjectType);
}
public ActionResult Create()
{
var obj = GetObject()
return View(obj);
}
Und so entschied ich, dass Reflexion hier am einfachsten war. Ich bin damit einverstanden, dass angesichts der anfänglichen Aussage der Frage die am besten geeignete Antwort, um sie als richtig zu markieren, die war, die die new () - Einschränkung verwendet. Ich habe das behoben.
Schauen Sie sich new Constraint an
public class MyClass<T> where T : new()
{
protected T GetObject()
{
return new T();
}
}
T
könnte eine Klasse sein, die keinen Standardkonstruktor hat. In diesem Fall wäre new T()
eine ungültige Anweisung. Die Einschränkung new()
besagt, dass T
einen Standardkonstruktor haben muss, der new T()
legal macht.
Sie können dieselbe Einschränkung auf eine generische Methode anwenden:
public static T GetObject<T>() where T : new()
{
return new T();
}
Wenn Sie Parameter übergeben müssen:
protected T GetObject(params object[] args)
{
return (T)Activator.CreateInstance(typeof(T), args);
}
Warum hat niemand vorgeschlagen, Activator.CreateInstance
?
http://msdn.Microsoft.com/en-us/library/wccyzw83.aspx
T obj = (T)Activator.CreateInstance(typeof(T));
Eine andere Möglichkeit ist die Reflexion:
protected T GetObject<T>(Type[] signature, object[] args)
{
return (T)typeof(T).GetConstructor(signature).Invoke(args);
}
Zur Vervollständigung besteht die beste Lösung darin, häufig ein Factory-Funktionsargument zu fordern:
T GetObject<T>(Func<T> factory)
{ return factory(); }
und nenne es so etwas:
string s = GetObject(() => "result");
Hiermit können Sie bei Bedarf verfügbare Parameter anfordern oder verwenden.
Die neue Einschränkung ist in Ordnung, aber wenn Sie benötigen, dass T auch ein Wertetyp ist, verwenden Sie Folgendes:
protected T GetObject() {
if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
return default(T);
} else {
return (T)Activator.CreateInstance(typeof(T));
}
}
Da dies mit C # 4 markiert ist. Mit dem Open-Source-Framework ImpromptuIntereface ruft es den Konstruktor mit dlr auf und ist bedeutend schneller als Activator, wenn Ihr Konstruktor Argumente hat, und vernachlässigbar langsamer, wenn dies nicht der Fall ist. Der Hauptvorteil ist jedoch, dass Konstruktoren mit optionalen C # 4.0-Parametern korrekt behandelt werden, was Activator nicht tut.
protected T GetObject(params object[] args)
{
return (T)Impromptu.InvokeConstructor(typeof(T), args);
}
Um das zu bekommen, habe ich folgenden Code ausprobiert:
protected T GetObject<T>()
{
T obj = default(T);
obj =Activator.CreateInstance<T>();
return obj ;
}