Ceci est essentiellement ce que la contrainte new()
se résume à:
class Factory<T> where T : new()
{
public T Create()
{
return new T();
// ^^^^^^^
// this requires the new() type constraint.
}
}
Maintenant, vous n'êtes pas autorisé à transmettre des arguments au constructeur. Si vous voulez néanmoins initialiser l'objet nouvellement créé, vous pouvez réaliser ceci par exemple. en introduisant une contrainte supplémentaire:
interface ILikeBananas
{
double GreenBananaPreferenceFactor { get; set; }
}
class Factory<T> where T : ILikeBananas, new()
{
public T Create(double greenBananaPreferenceFactor)
{
ILikeBananas result = new T();
result.GreenBananaPreferenceFactor = greenBananaPreferenceFactor;
return (T)result;
// ^^^^^^^^^
// freely converting between ILikeBananas and T is permitted
// only because of the interface constraint.
}
}
Notez qu'une autre façon d'instancier un objet est par Activator.CreateInstance
, qui vous donne une plus grande liberté, comme le passage d'arguments directement à un constructeur.
Activator.CreateInstance
ne nécessite pas strictement la contrainte new()
; cependant, le type instancié doit toujours fournir un constructeur approprié.
Bien que ce soit une bonne réponse, je déteste personnellement quand quelqu'un écrit un 'Factory' avec une contrainte 'where T: new()' tout en disant que tous les objets '' T' doivent être instanciés en utilisant cette usine! " Comme, si vous voulez vraiment limiter l'instanciation à votre usine, ne * demandez * pas qu'elle soit instanciable en dehors de votre usine! –
_ @ Dan Tao, hmm ... Vous avez certainement un point là. Notez cependant que je n'ai * pas * dit * n'importe où dans ma réponse que 'Factory' devrait être le créateur * exclusif * d'éléments de type 'T'. C'était simplement l'exemple le plus simple auquel je pouvais penser; peut-être le nom de type 'Usine ' suggère trop. –
stakx