4

I read this question, and am trying to do something like:

static class ExtentionMethods
{
    static public void MyReset<T>(this T col)
    {
        Console.WriteLine("Not a collection!");
    }

    static public void MyReset<T, U>(this T col) where T : ICollection<U>
    {
        col.Clear();
        Console.WriteLine("Cleared!");
    }

    // and maybe more overload for T : IWhatevetInterface<U>
}

so that List<T> and whoever implement ICollection<T> would choose the second method, while MyClass (MyClass is just some class that not implementing ICollection, of course) would choose the first, for example:

List<int> list1 = new List<int>();
list1.MyReset<List<int>, int>(); // "Cleared!"
MyClass x = new MyClass(); 
x.MyReset(); // "Not a collection!"

It works fine, but the problem is, how can I avoid writing <List<int>, int> for list1.MyReset<List<int>, int>()? I'd like to simply writing list1.MyReset().

The goal is to sustain the ability to distinguish ICollection<T> and other classes, but also not to explicitly providing the generic parameters.

Responding to comment: I'm planning to add more overloads, so the case is not only Yes-Collection and Not-Collection.

Community
  • 1
  • 1
Marson Mao
  • 2,935
  • 6
  • 30
  • 45
  • 3
    Why not just not have the "not a collection" override? Then bad code won't compile, rather than failing at runtime. – Blorgbeard Aug 06 '15 at 04:40
  • @Blorgbeard I'm planning to add more overloads for example `T : IResetable`, `T: IWhateverYouLike`, etc; So I need to let them match the exact overload. – Marson Mao Aug 06 '15 at 04:46

1 Answers1

4

C# does not use generic constraints in its type-inference algorithm.

However, it doesn't look like you actually need type-constraints. You could simplify your code like this, which does work:

static public void MyReset(this object col)
{
    Console.WriteLine("Not a collection!");
}

static public void MyReset<T>(this ICollection<T> col)
{
    col.Clear();
    Console.WriteLine("Cleared!");
}

static public void MyReset<T>(this IWhateverYouLike<T> col)
{
    col.ClearItIfYouLike();
    Console.WriteLine("Cleared!");
}
Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • sorry, it's my bad that not clarifying there are more than 2 possibilities, please see my edited question – Marson Mao Aug 06 '15 at 04:51
  • You can still have more than two possibilities - see my edit. Does this work for you? – Blorgbeard Aug 06 '15 at 04:53
  • @MarsonMao This answer is really the only viable approach. Your use case doesn't really make sense - Why use templates when you've explicitly said you want to find only `ICollection` types? – Rob Aug 06 '15 at 04:58
  • @Blorgbeard I tested your solution and it looks like what I need, thanks! Didnt realize that I can use a non-generic version for the general case! – Marson Mao Aug 06 '15 at 05:04
  • @Rob What do you mean? Which part of the template approach is wrong? – Marson Mao Aug 06 '15 at 05:06