213 votes

C # Créer un nouveau T ()

Vous pouvez voir ce que j'essaie (mais pas) à voir avec le code suivant:

protected T GetObject()
{
    return new T();
}

Toute aide serait grandement appréciée.

EDIT:

Le contexte était comme suit. J'ai été jouer avec un contrôleur de classe pour tous les contrôleurs de dériver de l', avec des méthodes standardisées. Donc, dans le contexte, j'avais besoin de créer une nouvelle instance de l'objet du type de contrôleur. Ainsi, au moment de la rédaction, c'était quelque chose comme:

public class GenericController<T> : Controller
{
    ...

    protected T GetObject()
    {
        return (T)Activator.CreateInstance(ObjectType);
    }        

    public ActionResult Create()
    {
        var obj = GetObject()

        return View(obj);
    }

Et j'ai donc décidé de réflexion a été plus facile ici. Je suis d'accord que, certainement, compte tenu de la déclaration initiale de la question, la réponse la plus appropriée pour marquer comme correcte a été l'une à l'aide de la contrainte new (). J'ai corrigé ça.

Cheers!

Tim.

512voto

Alex Aza Points 29204

Jetez un oeil à la nouvelle Contrainte

public class MyClass<T> where T : new()
{
    protected T GetObject()
    {
        return new T();
    }
}

T pourrait être une classe qui ne possède pas de constructeur par défaut: dans ce cas - new T() serait une instruction non valide. L' new() contrainte dit qu' T doit avoir un constructeur par défaut, ce qui rend new T() juridique.

Vous pouvez appliquer la même contrainte à une méthode générique:

public static T GetObject<T>() where T : new()
{
    return new T();
}

[MODIFIER]

Si vous avez besoin de passer des paramètres:

protected T GetObject(params object[] args)
{
    return (T)Activator.CreateInstance(typeof(T), args);
}

119voto

Steve Points 18193

Pourquoi personne n'a suggéré Activator.CreateInstance ?

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

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

31voto

Sean Thoman Points 2636

Une autre façon consiste à utiliser la réflexion:

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

21voto

Lukas Cenovsky Points 2425

La nouvelle contrainte convient, mais si vous avez aussi besoin que T soit un type valeur, utilisez ceci:

 protected T GetObject() {
    if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
        return default(T);
    } else {
       return (T)Activator.CreateInstance(typeof(T));
    }
}
 

19voto

Joel Coehoorn Points 190579

Juste pour terminer, la meilleure solution ici est souvent de demander un argument de fonction d'usine:

 T GetObject<T>(Func<T> factory)
{  return factory(); }
 

et appelez ça quelque chose comme ça:

 string s = GetObject(() => "result");
 

Vous pouvez l'utiliser pour demander ou utiliser les paramètres disponibles, si nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X