Impossible de créer une instance du type de variable 'Item' car elle n'a pas la contrainte new()
J'essaie de tester une méthode-et d'obtenir une erreur:
Cannot create an instance of the variable type 'Item' because it does not have the new() constraint
Informations requises pour CI-DESSOUS:
public interface IHasRect
{
Rectangle Rectangle { get; }
}
Classe D'aide:
class Item : IHasRect
{
public Item(Point p, int size)
{
m_size = size;
m_rectangle = new Rectangle(p.X, p.Y, m_size, m_size);
}
}
Pour que la fonction soit testée, j'ai besoin d'instancier un objet...
public class SomeClass<T> where T : IHasRect
Le test:
public void CountTestHelper<Item>()
where Item : IHasRect
{
Rectangle rectangle = new Rectangle(0, 0, 100, 100);
SomeClass<Item> target = new SomeClass<Item>(rectangle);
Point p = new Point(10,10);
Item i = new Item(p, 10); // error here
...
}
[TestMethod()]
public void CountTest()
{
CountTestHelper<Item>();
}
J'essaie de comprendre ce que signifie cette erreur, ou comment la corriger, en lisant http://msdn.microsoft.com/en-us/library/d5x73970.aspx et http://msdn.microsoft.com/en-us/library/x3y47hd4.aspx - mais il n'aide pas.
Je ne comprends pas cette erreur - j'ai déjà contraint le "SomeClass" à être de type. Je ne peux pas contraindre la classe de Test entière (la classe de test unitaire générée par Visual Studio, qui contient tous les tests) - j'obtiendrai un certain nombre d'autres erreurs sinon. La classe de l'Élément n'est pas n'importe quel modèle...
Aidez-moi à corriger cette erreur. Merci.
3 réponses
Le Item
dans la ligne:
Item i = new Item(p, 10);
Fait référence au paramètre de type générique Item
de la méthode CountTestHelper
, pas à la classe Item
. Modifier le nom du paramètre générique, par exemple
public void CountTestHelper<TItem>() where TItem : IHasRect
{
Rectangle rectangle = new Rectangle(0, 0, 100, 100);
SomeClass<TItem> target = new SomeClass<TItem>(rectangle);
Point p = new Point(10,10);
Item i = new Item(p, 10);
...
}
Vous pouvez également qualifier complètement le nom de la classe Item
que vous souhaitez créer:
public void CountTestHelper<Item>() where Item : IHasRect
{
Rectangle rectangle = new Rectangle(0, 0, 100, 100);
SomeClass<Item> target = new SomeClass<Item>(rectangle);
Point p = new Point(10,10);
SomeNamespace.Item i = new SomeNamespace.Item(p, 10);
}
Vous ne pouvez pas initialiser L'objet de type générique sauf si vous le marquez comme implémentant le constructeur par défaut en utilisant new
mot-clé:
public void CountTestHelper<Item>() where Item : IHasRect, new()
{
Rectangle rectangle = new Rectangle(0, 0, 100, 100);
SomeClass<Item> target = new SomeClass<Item>(rectangle);
Point p = new Point(10,10);
Item i = new Item(); // constructor has to be parameterless!
...
}
D'autre part, si vous essayez d'initialiser Item
type d'objet défini ailleurs dans l'application, essayez d'utiliser l'espace de noms avant:
MyAppNamespace.Item i = new MyAppNamespace.Item(p, 10);
Parce que beaucoup de gens arrivent ici par la question tilte (qui est très générique et correspond au message du compilateur) permettez-moi de donner une réponse plus détaillée sur l'erreur de compilation itsef.
Vous utilisez des génériques dans une méthode. Le compilateur ne sait pas quel type il recevra et il n'est donc pas garanti que votre type ait un interpréteur sans paramètre. Par exemple:
class A {
A(int i){ ... }
}
class B { ... }
public void MyMethod<T>(){
T t = new T(); //This would be fine if you use 'MyMethod<B>' but you would have a problem calling 'MyMethod<A>' (because A doesn´t have a parameterless construtor;
}
Pour résoudre ce problème, vous pouvez indiquer au compilateur que votre paramètre générique a un interpréteur sans paramètre. C'est fait en définissant des contraintes:
public void MyMethod<T>() where T: new(){
T t = new T(); //Now it's ok because compiler will ensure that you only call generic method using a type with parameterless construtor;
}
Plus d'informations sur les contraintes du constructeur peuvent être trouvées ici: https://msdn.microsoft.com/en-us/library/bb384067.aspx