Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

an I prevent a specific type using generic restrictions

I have an overload method - the first implementation always returns a single object, the second implementation always returns an enumeration.

I'd like to make the methods generic and overloaded, and restrict the compiler from attempting to bind to the non-enumeration method when the generic type is enumerable...

class Cache
{
    T GetOrAdd<T> (string cachekey, Func<T> fnGetItem)
        where T : {is not IEnumerable}
    {
    }

    T[] GetOrAdd<T> (string cachekey, Func<IEnumerable<T>> fnGetItem)
    {
    }
}

To be used with...

{
    // The compile should choose the 1st overload
    var customer = Cache.GetOrAdd("FirstCustomer", () => context.Customers.First());

    // The compile should choose the 2nd overload
    var customers = Cache.GetOrAdd("AllCustomers", () => context.Customers.ToArray());
}

Is this just plain bad code-smell that I'm infringing on here, or is it possible to disambiguate the above methods so that the compiler will always get the calling code right?

Up votes for anyone who can produce any answer other than "rename one of the methods".

like image 698
Mark Avatar asked Oct 08 '10 13:10

Mark


1 Answers

Rename one of the methods. You'll notice that List<T> has an Add and and AddRange method; follow that pattern. Doing something to an item and doing something to a sequence of items are logically different tasks, so make the methods have different names.

like image 119
Eric Lippert Avatar answered Sep 27 '22 17:09

Eric Lippert