hogwash
hogwash

Reputation: 33

The type cannot be used as type 'T' in the generic type or method. There is no implicit reference conversion from to

I'm trying to write a generic method to check if List is null or empty and throw an exception.

This is what I have:

public static void IsNullOrEmpty<T>(T argument) where T : List<T>
{
   if (argument == null || argument.Count == 0)
   {
        throw new ArgumentException("Argument " + nameof(argument) + " can't be null or empty list.");
   }
}

The problem is with calling this method; I trying to call this method like this:

ThrowIf.Argument.IsNullOrEmpty<List<ParameterServiceReference.Parameter>>(options.Parameters);

Where options.Parameters is type of: List<ParameterServiceReference.Parameter>.

I'm getting this error:

There is no implicit reference conversion from 'System.Collections.Generic.List<ParameterServiceReference.Parameter>' to 'System.Collections.Generic.List<System.Collections.Generic.List<ParameterServiceReference.Parameter>>

If I call method like this:

ThrowIf.Argument.IsNullOrEmpty<ParameterServiceReference.Parameter>(options.Parameters);

I get this error:

cannot convert from 'System.Collections.Generic.List<Project.Layer.ParameterServiceReference.Parameter>' to 'Project.Layer.ParameterServiceReference.Parameter'

Is this kind of generic method possible with generic collection or not, in the solution I will have many generic lists of different classes and I think it's not smart to write so many overloaded methods.

Upvotes: 3

Views: 2378

Answers (3)

Mukesh Adhvaryu
Mukesh Adhvaryu

Reputation: 646

You can have something like this:

public static void IsNullOrEmpty<S,T>(T argument) where T : List<S>
{
    if (argument == null || argument.Count == 0)
    {
        throw new ArgumentException("Argument " + nameof(argument) + " can't be null or empty list.");
    }
}

Now you can call your method:

ThrowIf.Argument.IsNullOrEmpty<ParameterServiceReference.Parameter, List<ParameterServiceReference.Parameter>>(options.Parameters);

Upvotes: 0

Servy
Servy

Reputation: 203830

You generic constraint specifically says that the parameter needs to be some type that is a List where the generic type of the list is itself. When you say where T : List<T> you're saying that the generic argument, T, needs to be a List<T> where T is the type you're adding the constraint for.

What you should really do here is just have the method accept a List<T>, not a T where T is a List:

public static void IsNullOrEmpty<T>(List<T> argument) { //...

Upvotes: 2

Luaan
Luaan

Reputation: 63772

You can't have a constraint that's T : List<T>, just like you can't have a type MyList that inherits from MyList (or type T that inherits from List<T>).

Just use public static void IsNullOrEmpty<T>(List<T> argument)

Upvotes: 0

Related Questions