Подтвердить что ты не робот

Невозможно создать экземпляр типа переменной "Item", потому что у него нет ограничения new()

Я пытаюсь проверить метод - и получаю сообщение об ошибке:

Невозможно создать экземпляр типа переменной "Item", поскольку он не имеет ограничения new()

Необходимая информация для ниже:

public interface IHasRect
{
    Rectangle Rectangle { get; }
}

Класс помощника:

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

Чтобы проверить функцию, мне нужно создать экземпляр объекта...

public class SomeClass<T> where T : IHasRect

Тест:

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

Я пытаюсь понять, что означает эта ошибка или как ее исправить, прочитав http://msdn.microsoft.com/en-us/library/d5x73970.aspx и http://msdn.microsoft.com/en-us/library/x3y47hd4.aspx, но это не помогает.

Я не понимаю эту ошибку - я уже ограничил тип SomeClass. Я не могу ограничить весь класс Test (класс модульных тестов, сгенерированный Visual Studio, который содержит все тесты) - в противном случае я получу ряд других ошибок. Класс Item не имеет шаблона...

4b9b3361

Ответ 1

Item в строке:

Item i = new Item(p, 10);

ссылается на параметр типового типа Item метода CountTestHelper, а не на класс Item. Изменение имени общего параметра, например.

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

альтернативно вы можете полностью квалифицировать имя класса Item, который хотите создать:

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

Ответ 2

Вы не можете инициализировать объект Generic type, если вы не помечаете его как реализующий конструктор по умолчанию, используя ключевое слово new:

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

С другой стороны, если вы пытаетесь инициализировать объект Item типа, определенного где-то еще в приложении, попробуйте использовать пространство имен до:

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

Ответ 3

Поскольку многие люди попадают сюда на вопрос tilte (который очень общий и соответствует сообщению компилятора), позвольте мне дать более подробный ответ об ошибке компиляции itsef.

В методе используются дженерики. Компилятор не знает, какой тип он получит, и, следовательно, не является гарантией того, что ваш тип имеет бесступенчатый конструктор. Для примера:

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

Чтобы решить эту проблему, вы можете сообщить компилятору, что ваш общий параметр имеет беззаметный конструктор. Это делается путем определения ограничений:

public void MyMethod<T>()  where T: new(){
    T t = new T(); //Now it ok because compiler will ensure that you only call generic method using a type with parameterless construtor;
}

Более подробную информацию о ограничениях конструктора можно найти здесь: https://msdn.microsoft.com/en-us/library/bb384067.aspx