The type 'int' cannot be used as type parameter 'T' in the generic method. There is no boxing conversion from 'int'

958 Views Asked by At

I'm trying to implement Sorting trash container. Unfortunately, I'm not so experienced in C# yet and I'm obviously not getting the point of handling the generic method and corresponding interfaces. Below is some part of my code.

static void RandomNumbers()
{
    Random random = new Random((int)DateTime.Now.Ticks);
    SortedTrashContainer<int> trash = new SortedTrashContainer<int>(10);
    for (int i = 0; i < trash.Capacity; i++)
        trash.Add(random.Next(10));
    Console.WriteLine("== Random numbers ==");
    foreach (var item in trash)
        Console.Write(item + " ");
}
class SortedTrashContainer<T> where T : IContainer<T>, IComparable<T>
{
    private int size;
    private int pointer = 0;
    private T[] items;
    public int Capacity => size;
    public SortedTrashContainer(int capacity)
    {
        if (capacity >= 0)
        {
            size = capacity;
            items = new T[capacity];
        }
        else
            throw new ArgumentOutOfRangeException();
    }
    public void Add(T item)
    {
        if (pointer < size)
        {
            items[pointer++] = item;
            Sort(items);
        }
        else
            throw new InvalidOperationException();
    }
    private void Sort(T[] array)
    {
        int top = array.Length - 1;
        int indexOfLargest;
        do
        {
            indexOfLargest = 0;
            for (int i = 0; i <= top; i++)
            {
                if (array[indexOfLargest].CompareTo(array[i]) < 0)
                    indexOfLargest = i;
            }
            IComparable temp = (IComparable)array[top];
            array[top] = array[indexOfLargest];
            array[indexOfLargest] = (T)temp;
            top--;
        } while (top > 0);
    }
}

In the line where I declare an object trash with the reference to SortedTrashContainer and passing an inttype as parameter I'm getting compilation error "The type 'int' cannot be used as type parameter T in the generic method SortedTrashContainer<T>. There is no boxing conversion from int to MyNameSpace.IContainer<int>". Unfortunately I'm really stuck here. Just not getting the point, what can resolve this issue.

2

There are 2 best solutions below

1
On

If you don't implement your class from IContainer and make items properties public your code will work.

0
On

I came across this question when I had just run into the same issue. The comments left on the question do for the most part answer the question and try to explain it but seeing as how a few hundred other people have viewed this, the question is unresolved, and I feel as though I can offer a bit more of an explanation, I am going to provide my own answer as to why, in addition to what caused my problem that gave me this error.

In the case of what happened for SortedTrashContainer:
In the definition for SortedTrashContainer, it says that the type 'T' must inherit from "IContainer" and "IComparable". The moment you try to declare an object SortedTrashContainer, it checks what int (Actually Int32) is inherited from, and if it is not both "IContainer" and "IComparable", you will get this error. I was able to reproduce it in OPs code by using the class and just replacing IContainer with another generic like IList. The Int32 struct implements the following interfaces:
public struct Int32 : IComparable, IComparable<Int32>, IConvertible, IEquatable<Int32>, IFormattable
As you can see, int inherits from IComparable, so no errors are thrown there, however, the user defend interface is NOT one of these and so you will receive a compiler error for trying to use the type. In order to make the code work, you must provide an appropriate type and values to the class OR change how your class defines/restricts the type.

In my specific case:
Having a generic class inherit from another generic class or interface places specific restrictions on what types 'T' can be based upon all of the inherited interfaces and/or the classes restrictions on their type parameters. As an example, if you have a generic class, with generic type 'T', that says that the type 'T' has to be a struct, and then you create another generic class with type 'U' which inherits from the first passing the generic type 'U' into the first class as its type parameter, your type U must be a type of struct, otherwise there a possibility that you can define type 'U' as being a type of class and then the generic restriction on the base classes type 'T' is violated. To prevent this from happening, you MUST restrict the type 'U' to being only that of a struct.

For me, I was tired and wasn't thinking clearly and I had never seen the error before, so I did a quick search to see what it was and that brought me here. For my code, I had a generic class which restricted type 'T' to implementing 'IBehaviour':

public abstract class ManagedBehaviourGroup<T> where T : IBehaviour {
    public abstract bool IsRegistered(T behaviour);
    public abstract void RegisterBehaviour(T behaviour);
    public abstract void UnregisterBehaviour(T behaviour);
}

I then tried to extend the abstract generic class like so:

public class ManagedBehaviourGroupSingle<T> : ManagedBehaviourGroup<T> {

}

Because I had never restricted the type T in 'ManagedBehaviourGroupSingle' to only ones which implement 'IBehaviour' I was getting yelled at by my compiler. The solution then is pretty straight forward being:

public class ManagedBehaviourGroupSingle<T> : ManagedBehaviourGroup<T> where T : IBehaviour  {

}

I hope this helps anyone who may need it.