mcmorry
mcmorry

Reputation: 132

cannot convert Key<T> expression to type Key<T>?

I can't find what's wrong in this code and the error didn't help me much:

public class Track<T> {

    readonly List<Key<T>> _keys = new List<Key<T>>();

    public void AddKey<T>(float time, T value) {
        var key = new Key<T> {
            Time = time,
            Value = value
        };
        _keys.Add(key); // <== Error: cannot convert Key<T> expression to type Key<T>
    }
}

public struct Key<T> {
    public float Time;
    public T Value;
}

Upvotes: 1

Views: 71

Answers (3)

Sweeper
Sweeper

Reputation: 274480

The T type in your AddKey method is not the same type as the generic type argument T of your Track<T> class.

So the variable key's type is the Key<T> where T is defined in the scope of the method. However, _keys.Add needs an argument of type Key<T> where T is defined in the class declaration. That's why the error appears.

To fix this, simply remove the T from the method so it looks like this:

public void AddKey(float time, T value) { 

Now the T in T value refers to the class's generic type argument because there is no other T that it can refer to!

Upvotes: 0

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186833

You've redefined template in the method:

// Here's one "T"
public class Track<T> {
    readonly List<Key<T>> _keys = new List<Key<T>>();

    // ... And here is a different "T" which hides original (from Track<T>) one 
    // the declaration equals to 
    // public void AddKey<K>(float time, K value) {
    public void AddKey<T>(float time, T value) {
      // T has been redefined, so "new Key<T>" (with redefined T)
      // is not equal to Key<T> from List<Key<T>> _keys which uses class template T
      ... 
    }
}

try removing T from the method:

public class Track<T> {
    ...    
    // No "<T>" declaration here, uses "T" from Track<T>
    public void AddKey(float time, T value) {
        ...
    }
}

Upvotes: 1

eocron
eocron

Reputation: 7546

The reason you get this is because you define template class AND also a template method. If you change it to AddKey<K> you will understand what Im talking about. Try to change it like this:

public class Track<T> {

    readonly List<Key<T>> _keys = new List<Key<T>>();

    public void AddKey(float time, T value) {
        var key = new Key<T> {
            Time = time,
            Value = value
        };
        _keys.Add(key); // <== Error: cannot convert Key<T> expression to type Key<T>
    }
}

public struct Key<T> {
    public float Time;
    public T Value;
}

Upvotes: 0

Related Questions