it-swarm.com.de

C # Neu erstellen T()

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.

142
Hanshan

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);
}
370
Alex Aza

Warum hat niemand vorgeschlagen, Activator.CreateInstance?

http://msdn.Microsoft.com/en-us/library/wccyzw83.aspx

T obj = (T)Activator.CreateInstance(typeof(T));
56
Steve

Eine andere Möglichkeit ist die Reflexion:

protected T GetObject<T>(Type[] signature, object[] args)
{
    return (T)typeof(T).GetConstructor(signature).Invoke(args);
}
28
Sean Thoman

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.

18
Joel Coehoorn

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));
    }
}
14
Lukas Cenovsky

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);
}
7
jbtule

Um das zu bekommen, habe ich folgenden Code ausprobiert:

  protected T GetObject<T>()
    {
        T obj = default(T);
        obj =Activator.CreateInstance<T>();
        return obj ;
    }
4
UJS