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

C#TemplatesGenericsCompiler Errors

C# Problem Overview


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

C# Solutions


Solution 1 - C#

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 2 - C#

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

Solution 3 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThaliaView Question on Stackoverflow
Solution 1 - C#MarcinJuraszekView Answer on Stackoverflow
Solution 2 - C#Zé CarlosView Answer on Stackoverflow
Solution 3 - C#LeeView Answer on Stackoverflow