63

メソッドをテストしようとしていますが、エラーが発生します:

new()制約がないため、変数タイプ'Item'のインスタンスを作成できません

以下に必要な情報:

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クラスにはテンプレートがありません...

4

3 に答える 3

154

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);
于 2013-02-04T22:32:29.653 に答える
39

多くの人が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's 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を参照してください。

于 2015-03-30T11:40:30.480 に答える
17

行の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);  
}
于 2013-02-04T22:32:43.307 に答える