akka16
akka16

Reputation: 83

Single Linked List with Generic Implementation

I have created a single linked list with generic implementation. But the Add(..) method is giving compilation error saying:

Error 4 Cannot implicitly convert type 'ds.MyNode< T >' to 'ds.MyNode< T >'

Following the code implementation:

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

I'm not sure what am I missing here, The error is confusing because both the types it says aren't implicitly convertible are same. Any help is appreciated.

I am compiling it against .Net 4.0

Thanks.

Upvotes: 2

Views: 148

Answers (2)

awesoon
awesoon

Reputation: 33651

Just remove the <T> generic type from Add method, since your class is already generic.

It is possible for class and method to have the same name of generic type (docs):

If you define a generic method that takes the same type parameters as the containing class, the compiler generates warning CS0693 because within the method scope, the argument supplied for the inner T hides the argument supplied for the outer T. If you require the flexibility of calling a generic class method with type arguments other than the ones provided when the class was instantiated, consider providing another identifier for the type parameter of the method, as shown in GenericList2<T> in the following example.

class GenericList<T>
{
    // CS0693 
    void SampleMethod<T>() { }
}

class GenericList2<T>
{
    //No warning 
    void SampleMethod<U>() { }
}

So, you should probably enable compile warnings. 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

Upvotes: 7

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149528

This:

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

Means that T is over shadowing your class level T declaration, hence the compiler looks at them as different types. Removing T will work, as it is clear that you want your classes T declaration.

Just so you visually see it, this will work as well (don't use this):

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

Since you're now explicitly telling the compiler TOther is of type T or derived.

Upvotes: 3

Related Questions