Home > OS >  IReadOnlyCollection derived class extension returning original type
IReadOnlyCollection derived class extension returning original type

Time:11-26

I'm a bit lost here (maybe because it's Friday)

I want to write a simple "throw if null or empty" extension helper that I can use in constructors like (e.g.)

public class MyClass
{
    public MyClass(params MyType[] parameters)
    {
        _parameters = parameters.ThrowIfNullOrEmpty();
    }

So I was trying to write this method like:

public static T ThrowIfNullOrEmpty<T, V>(this T? collection, [CallerArgumentExpression("collection")] string? paramName = null)
    where T : IReadOnlyCollection<V>
{
    if (collection is null ||
        collection.Count == 0)
    {
        throw new ArgumentException($"{paramName} is null or empty");
    }

    return collection;
}

But that doesn't work, as I get an "Arguments cannot be inferred from usage".

The issue here I that I have to use ThrowIfNullOrEmpty<T, V>, as where T : IReadOnlyCollection<V> requires a type parameter.

Isn't there a way to say "I don't care what V is, as long as T is a form of IReadOnlyCollection"?

CodePudding user response:

How about assigning with an out parameter?

parameters.ThrowIfNullOrEmpty(out _parameters);

public static void ThrowIfNullOrEmpty<TElem, TColl>(
    this IReadOnlyCollection<TElem>? collection,
    out TColl? output,
    [CallerArgumentExpression("collection")] string? paramName = null
) where TColl : IReadOnlyCollection<TElem>
{
    if (collection is null || collection.Count == 0)
    {
        throw new ArgumentException($"{paramName} is null or empty");
    }

    output = (TColl)collection;
}

CodePudding user response:

So you want a method that takes any collection, and returns that collection of exactly that type, unless the parameter is null or an empty collection, then have it throw, without having to specify type parameters (so, leveraging inference).

In that case I'd go with the non-generic ICollection:

public static TCollection ThrowIfNullOrEmpty<TCollection>(this TCollection collection, [CallerArgumentExpression("collection")] string? paramName = null)
    where TCollection : ICollection
{
    if (collection is null || collection.Count == 0)
    {
        throw new ArgumentException($"{paramName} is null or empty");
    }

    return collection;
}
  • Related