【问题标题】:Single Linked List with Generic Implementation具有通用实现的单链表
【发布时间】:2015-06-26 08:19:28
【问题描述】:

我创建了一个具有通用实现的单链表。但是 Add(..) 方法给出编译错误:

错误 4 无法将类型 'ds.MyNode' 隐式转换为 'ds.MyNode'

以下代码实现:

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 编译它

谢谢。

【问题讨论】:

  • 我认为您不希望这些 setter 公开
  • 是的,我同意,但这只是在 SE 上发布的示例代码,所以道具是自动生成的。

标签: c# generics linked-list


【解决方案1】:

只需从 Add 方法中删除 &lt;T&gt; 泛型类型,因为您的类已经是泛型的。

类和方法可以具有相同的泛型类型名称(docs):

如果您定义了一个泛型方法,它采用与包含类相同的类型参数,编译器会生成warning CS0693,因为 在方法范围内,为内部 T 提供的参数隐藏 为外部 T 提供的参数。如果您需要 使用类型参数调用泛型类方法的灵活性 除了在类被实例化时提供的那些, 考虑为方法的类型参数提供另一个标识符,如以下示例中的GenericList2&lt;T&gt; 所示。

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

【讨论】:

  • 是的,因为我对内部和外部声明都使用了相同的通用标识符“T”,这让我很困惑,无法找出错误。如果我使用不同的标识符,该解决方案会很早就让我印象深刻。感谢您的解释。也忽略这个警告是不明智的。 :)
【解决方案2】:

这个:

public void Add<T>(MyNode<T> node)

意味着T 过度遮蔽了您的类级别 T 声明,因此编译器将它们视为不同的类型。删除 T 将起作用,因为很明显你想要你的类 T 声明。

只是为了让您直观地看到它,这也可以(不要使用)

public void Add<TOther>(MyNode<T> node) where TOther : T

因为您现在明确告诉编译器 TOtherT 类型或派生的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 2013-12-03
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多