Cannot create an instance of the variable type 'Item' because it does not have the new() constraint

58,574

Solution 1

The Item in the line:

Item i = new Item(p, 10);

refers to the generic type parameter Item of the CountTestHelper method, not the class Item. Change the generic parameter name e.g.

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

alternatively you can fully qualify the name of the Item class you want to create:

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

Solution 2

You can't initialize Generic type object unless you mark it as implementing default constructor using new keyword:

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!
    ...
 }

On the other hand, if you're trying to initialize an Item type object defined somewhere else in the application try using the namespace before it:

MyAppNamespace.Item i = new MyAppNamespace.Item(p, 10);

Solution 3

Because many people get here by the question tilte (which is very generic and matches the compiler message) let me give a more detailed answer about the compiling error itsef.

You are using generics in a method. The compiler doesn´t know which type it will receive and thus it is not warranted that your type has a parameterless construtor. For ex:

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

To resolve this, you can tell the compiler that your generic parameter has a parameterless construtor. This is done by defining constraints:

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

More information about constructor constraints may be found here: https://msdn.microsoft.com/en-us/library/bb384067.aspx

Share:
58,574
Thalia
Author by

Thalia

Junior developer exploring image processing and driver development

Updated on December 10, 2020

Comments

  • Thalia
    Thalia over 3 years

    I am trying to test a method - and getting an error:

    Cannot create an instance of the variable type 'Item' because it does not have the new() constraint

    Required information for below:

    public interface IHasRect
    {
        Rectangle Rectangle { get; }
    }
    

    Helper class:

    class Item : IHasRect
    {
        public Item(Point p, int size)
        {
            m_size = size;
            m_rectangle = new Rectangle(p.X, p.Y, m_size, m_size); 
        }
    }
    

    For the function to be tested, I need to instantiate an object...

    public class SomeClass<T> where T : IHasRect
    

    The 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>();
    }   
    

    I am trying to understand what this error means, or how to fix it, by reading http://msdn.microsoft.com/en-us/library/d5x73970.aspx and http://msdn.microsoft.com/en-us/library/x3y47hd4.aspx - but it doesn't help.

    I don't understand this error - I have already constrained the "SomeClass" to be of type. I cannot constrain the entire Test class (the unit test class generated by Visual Studio, which contains all the tests) - I will get a number of other errors otherwise. The Item class doesn't have any template...

  • Immortal Blue
    Immortal Blue over 11 years
    Except that you can only use the parameterless constructor with new(). I don't understand why they haven't fixed this! edit: Ahh, you've edited to mention that ;)
  • Thalia
    Thalia over 11 years
    'Item' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'Item' in the generic type or method 'CountTestHelper<Item>()'
  • Immortal Blue
    Immortal Blue over 11 years
    Also, note the answer from Lee, be sure that you're familiar with generics type definitions. Here, your "Item" class is NOT the class you defined earlier, it's just a place holder type that you're temporarily calling Item...
  • BaTTy.Koda
    BaTTy.Koda over 11 years
    You were seeing the same thing I was. I looked at it and was like "Wait, Item is a type parameter not a type.
  • R. Schreurs
    R. Schreurs over 9 years
    This answer it correct for the question. However, if you came here looking for a way to instantiate a property with a generic type, you will want to read the answer by @MarcinJuraszek.
  • Mr.Z
    Mr.Z about 7 years
    Public Sub MyMethod(Of T As New)() is the equivalent VB code, for those interested. More info available on MSDN.
  • joedotnot
    joedotnot about 5 years
    Is there a version that allow new(parameter1, parameter2, etc) for the generic T type?