-1

Given the following method:

public static void DisposeItems<T>(this ICollection<T?> collection)
    where T : class, IDisposable
{
    foreach (var item in collection)
    {
        item?.Dispose();
    }

    if (!collection.IsReadOnly)
    {
        collection.Clear();
    }
}

This is called in something like:

private static void CleanupNullable(List<TestClass?> collection)
{
    collection.DisposeItems();
}

private static void Cleanup(List<TestClass> collection)
{
    collection.DisposeItems();
}

The second gives the error: collection cannot be used to due difference of nullability in the reference types.

A similar implementation accepting IEnumerable<T?> works fine because IEnumerable is co-variant.

I cannot create an additional method accepting ICollection<T> because nullability is not part of the signature. Is there any way I can compile this as it worked pre-nullability?

Dropping the class constraint or changing it to class? gives errors when calling it with Collection<TestClass?> because TestClass? doesn't match constraint IDisposable.

  • Firstly it is not able to compile because of null operator. How can you call it as you mentioned `gives errors when calling it with Collection`? – Sh.Imran Aug 09 '20 at 01:52
  • I managed to make it work by surrounding the method with ```#nullable disable``` and ```#nullable restore```. It literally is now what it was before. It allows calling from a nullable context with non-nullable and nullable types. I was hoping for another way. – Manfred Brands Aug 09 '20 at 04:44
  • The shown code works for Collection but not for Collection. – Manfred Brands Aug 09 '20 at 04:53
  • How did you call this method? – Pavel Anikhouski Aug 09 '20 at 15:30

1 Answers1

0

This is because you've put the question mark in the wrong place. If your generic constraint doesn't care if a type is nullable, you add the question mark to the type in the where expression, rather than the argument list. Plus you need to add that "don't care" question mark to all of the constraints for that type.

public static void DisposeItems<T>(this ICollection<T> collection)
    where T : class?, IDisposable?
Jeremy Lakeman
  • 9,515
  • 25
  • 29