Tha*_*lia 41 c# generics templates compiler-errors
我试图测试一个方法 - 并得到一个错误:
public interface IHasRect
{
Rectangle Rectangle { get; }
}
Run Code Online (Sandbox Code Playgroud)
以下所需信息:
class Item : IHasRect
{
public Item(Point p, int size)
{
m_size = size;
m_rectangle = new Rectangle(p.X, p.Y, m_size, m_size);
}
}
Run Code Online (Sandbox Code Playgroud)
助手班:
public class SomeClass<T> where T : IHasRect
Run Code Online (Sandbox Code Playgroud)
对于要测试的函数,我需要实例化一个对象......
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>();
}
Run Code Online (Sandbox Code Playgroud)
考试:
public interface IHasRect
{
Rectangle Rectangle { get; }
}
Run Code Online (Sandbox Code Playgroud)
我试图通过阅读http://msdn.microsoft.com/en-us/library/d5x73970.aspx和http://msdn.microsoft.com/en-来了解此错误的含义或如何修复它.us/library/x3y47hd4.aspx - 但它没有帮助.
我不明白这个错误 - 我已经将"SomeClass"限制为类型.我不能约束整个Test类(由Visual Studio生成的单元测试类,其中包含所有测试) - 否则我将得到许多其他错误.Item类没有任何模板......
请帮我修复此错误.谢谢.
Mar*_*zek 114
除非使用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!
...
}
Run Code Online (Sandbox Code Playgroud)
另一方面,如果您尝试初始化Item应用程序中其他位置定义的类型对象,请尝试使用命名空间:
MyAppNamespace.Item i = new MyAppNamespace.Item(p, 10);
Run Code Online (Sandbox Code Playgroud)
Zé *_*los 30
因为很多人通过问题来到这里(这是非常通用的并且匹配编译器消息)让我给出关于编译错误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;
}
Run Code Online (Sandbox Code Playgroud)
要解决此问题,您可以告诉编译器您的泛型参数有一个无参数的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;
}
Run Code Online (Sandbox Code Playgroud)
有关构造函数约束的更多信息,请访问:https: //msdn.microsoft.com/en-us/library/bb384067.aspx
Lee*_*Lee 13
将Item在该行:
Item i = new Item(p, 10);
Run Code Online (Sandbox Code Playgroud)
指的是一般类型参数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);
...
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以完全限定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);
}
Run Code Online (Sandbox Code Playgroud)