我创建了一个包含通用实现的链表。但Add(..)方法给出了编译错误说:
错误4无法隐式转换类型' ds.MyNode< T>' to' ds.MyNode< T>'
遵循代码实现:
public class MyNode<T>
{
public MyNode(T content)
{
Content = content;
}
public T Content { get; set; }
public MyNode<T> Next { get; set; }
}
public class MyLinkedList<T>
{
private int size;
private MyNode<T> head;
private MyNode<T> tail;
public MyNode<T> Tail
{
get { return tail; }
set { tail = value; }
}
public int Count
{
get { return size; }
set { size = value; }
}
public MyNode<T> Head
{
get { return head; }
set { head = value; }
}
public void Add<T>(MyNode<T> node)
{
size++;
if (head == null)
{
head = tail = node;
}
else
{
tail.Next = node;
tail = node;
}
}
}
我不确定我在这里缺少什么,这个错误令人困惑,因为它所说的不可隐式转换的类型都是相同的。任何帮助表示赞赏。
我正在针对.Net 4.0进行编译
感谢。
答案 0 :(得分:7)
只需从<T>
方法中删除Add
泛型类型,因为您的类已经是通用的。
类和方法可以使用相同的泛型类型(docs):
如果您定义泛型方法,其与包含类相同的类型参数,则编译器会生成警告CS0693 ,因为 在方法范围内,为内部T隐藏提供的参数 为外部T 提供的参数。如果你需要的话 使用类型参数调用泛型类方法的灵活性 除了实例化课程时提供的, 考虑为方法的类型参数提供另一个标识符,如以下示例中的
GenericList2<T>
所示。class GenericList<T> { // CS0693 void SampleMethod<T>() { } } class GenericList2<T> { //No warning void SampleMethod<U>() { } }
因此,您应该启用编译警告。 Example of the compiler output from ideone.com:
prog.cs(39,22): warning CS0693: Type parameter `T' has the same name as the type parameter from outer type `Test.MyLinkedList<T>'
prog.cs(15,28): (Location of the symbol related to previous warning)
prog.cs(44,28): error CS0029: Cannot implicitly convert type `Test.MyNode<T> [prog, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]' to `Test.MyNode<T> [prog, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]'
prog.cs(48,26): error CS0029: Cannot implicitly convert type `Test.MyNode<T> [prog, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]' to `Test.MyNode<T> [prog, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]'
prog.cs(49,21): error CS0029: Cannot implicitly convert type `Test.MyNode<T> [prog, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]' to `Test.MyNode<T> [prog, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]'
Compilation failed: 3 error(s), 1 warnings
答案 1 :(得分:3)
此:
public void Add<T>(MyNode<T> node)
意味着T
超过了您的类级别T声明,因此编译器会将它们视为不同的类型。删除T
将起作用,因为很明显您希望您的类T
声明。
只是让你在视觉上看到它,这也会起作用(不要使用它):
public void Add<TOther>(MyNode<T> node) where TOther : T
由于您现在明确告诉编译器TOther
类型为T
或派生。