Best solution: do not go there in the first place . This is a bad design. You will notice that none of the infrastructure classes does this. The list has two methods: Add and AddRange. The first one adds one element, the second one adds a sequence of elements.
This is a bad design because you are writing a device to automatically generate errors. Consider again an example of a modified list:
List<object> myqueries = new List<object>(); myqueries.Add(from c in customers select c.Name); myqueries.Add(from o in orders where o.Amount > 10000.00m select o);
You expect to add two queries to the query list; if Add were overloaded to accept the sequence, then this would add the query results to the list, not the queries. You must be able to distinguish between a query and its results; they are logically completely different.
It is best to make the methods have two different names.
If you're damn tuned for this bad design, then if it hurts you when you do this, don't do it. Overload resolution is designed to find the best match. Do not try to clog the overload so that it does something even worse. Again, this is confusing and error prone. Solve the problem using a different mechanism. For example:
static void Frob(IEnumerable ts) // not generic! { foreach(object t in ts) Frob<object>(t); } static void Frob<T>(T t) { if (t is IEnumerable) Frob((IEnumerable) t); else // otherwise, frob a single T. }
Now, no matter what the user gives you - an array of T, an array of lists of T, regardless of whether you end up only frobbing one Ts.
But then again, this is almost certainly a bad idea. Do not do this. Two methods that have different semantics must have different names.
Eric Lippert
source share