Lower bound is the C++ term for returning the smallest index into a
sorted list such that inserting the search value at that index would
result in the list remaining sorted.
No, actually it's not. "Lower bound" is a broadly general phrase, usedin
the context of all sorts of programming languages, to mean a wide variety
of different things. In fact, in C/C++, the standard name for the binary
search function is "bsearch". That's the name of the function providedin
the CRT library.
It is similar to binary search,
except that it doesn't care whether the value exists or not in the
list;
There's nothing about "binary search" that implies the searched-for
element is in the collection being searched. In other words, what you
have _is_ a binary search.
[...]
The big problem with using .NET's binary search is that it may or may
not return the first possible index. It is not guaranteed to handle
duplicates, in other words. Even if it did, it would only work with a
List<T> or an Array, specifically - not a generic IList<T>.
That's all true. It's unfortunate that the BinarySearch() methods are
implementations on specific classes. I would guess that if they had done
it now, with extension methods providing a way to effectively implement
methods for interfaces instead of only on classes, it would be more
convenient.
That said, since it's trivial to scan backwards to find the first element
once any element has been found, I'm not entirely convinced it's a good
use of your time to reimplement the entire binary search algorithm, just
to get that behavior.

But if you really want to, or have to support
In my situation I have a delegate that looks like this:
public delegate int Comparison<TValue, TSearch>(TValue value, TSearch
search);
.NET has a delegate that looks like this:
public delegate int Comparison<T>(T x, T y);
When TValue is the same type as TSearch, the method signatures are the
same. It would be nice if there was a way to tell the compiler, "Hey,
the method signatures required by these different delegates are the
same. It's okay!".
Well, unfortunately that's just not how the type compatibility works in C#.
C# current has limited support for contravariance for generic delegate
types (for example, you can assign an EventHandler<EventArgs>-derived
value to an EventHandler<EventArgs> variable), and it appears that v4.0
will introduce some support for covariant generics.
But that compatibility depends on an inheritance relationship between the
types. What you're asking for is more like this:
class A<T>
{
public T i;
public T j;
}
class A<T, U>
{
public T i;
public U j;
}
and being able to write code like this:
A<T, U> a1 = new A<T, U>();
A<T> a2 = a1;
Sure, by human inspection we can tell that these types are essentially the
same. But they aren't actually _the same type_, nor are they inheriting
from each other (i.e. one is not a subclass of another). We have the same
problem with the delegates. A delegate type is a special kind of type,
but it's still a type, and the same type-compatibility rules have to apply.
C#/.NET also has type conversion (a special kind of compatibility,
different from casting), and you can provide user-defined conversions with
the "implicit" and "explicit" operators. But you can only define a
conversion either to or from the type in which the conversion is
declared. .NET doesn't already have a conversion like what you want, and
you can't implement it because you can't inherit delegate types.
You could do something similar with extension methods, providing a special
"Convert" method that does the wrapping. This doesn't avoid the wrapping,
but it would at least isolate that code, so that you could reuse it
wherever the situation comes up.
For that matter, the extension method could get really fancy and actually
create a new delegate instance using the target method of the passed-in
delegate. In other words, rather than returning a new delegate instance
that simply retains and calls the original delegate instance, you could
create a delegate instance that extracts the necessary information from
the original, incorporating that into a new delegate without having to
retain a reference to the original delegate instance.
Now, all that said, I am still not convinced that in this case you are
really in need of this behavior. In particular, there's not really any
reason that your binary search method needs access to the specific element
being searched for at all. It only ever uses it by passing it to the
comparison method, and so all you really need is a a delegate like this:
// Name this whatever you want, but since it takes just the one
// argument, I'd try to avoid something as generic as simply
"Comparison"
delegate int BinarySearchComparison<T>(T t);
In your "LowerBound()" method, you'd use the above as the delegate
argument, rather than Comparison<T, U> or Comparison<T>, and you'd simply
pass the current element, rather than the current element and some value
passed to the method (and of course the method would only have the two
arguments, with the TSearch element excluded altogether).
Then, it would be used something like this (equivalent to using
Comparison<T, U>):
int i = 123;
int lowerBound = LowerBound(customers, customer =>
customer.Id.CompareTo(i));
or this (equivalent to using Comparison<T>):
Customer customerToFind = ...;
int lowerBound = LowerBound(customers, customer =>
customer.CompareTo(customerToFind));
A couple of points: all that Comparer<T>.Default does is return a Comparer
instance that uses IComparable<T> on the type given. So if you aren't in
a situation where you need to pass something an actual Comparer instance,
you might as well just call IComparable<T> directly (as above).
Also note that I used the lambda expression syntax, which for stuff like
this helps make things somewhat more concise than the traditional
"delegate { }" anonymous method declaration.
Also note that the compiler can infer the type parameter for the method
from the arguments given, so there's no need to provide them in this
situation.
But most relevantly, note that I've incorporated the value you're looking
for directly in the lambda expression, rather than depending on the
LowerBound() method to pass that value in. The value is invariant for the
operation, and the search method itself never actually cares about it. So
there's no need to bother including it at all.
Other than the usual caveats about captured variables (which is what
happens here to your variable "i"), this is a much cleaner approach IMHO,
and side-steps the entire question of having a Comparison<T, U> versus a
I don't really want a debate about the genuine need for such a thing;
I am just saying it would be convenient in my situation.
And I'm just saying that there are probably ways to address the situation
in ways that are _even more_ convenient than what you have in mind.
This is for my personal use, so I don't see why it is anybody else's
business what I do with my code.
Frankly, that statement comes across as a bit hostile. I'm not sure
that's the impression you really want to make when all I or anyone else
here is trying to do is help.
But beyond that, it's "anybody else's business" because you made it our
business. You asked a question in the context of how to implement your
code, and that question can only be correctly answered with a reasonably
complete understanding of how you're using your code and what the actual
implementation is.
I've already deemed that I want to
write my code this way so there is no point looking for other
solutions.
Even if other solutions are superior to the approach you're using, meeting
the exact goals you're trying to achieve in even more convenient ways?
I'm just trying to make the signature of the method less of
an eye-sore.
But that's exactly what I'm trying to help you do.
I just asked a question; that's all.
And I've just answered the question, that's all. I don't see any reason
for you to get so defensive about it.
The fact is, as the person who is asking the question, you are in a VERY
poor position to make a determination as to what information is or is not
needed in order to properly answer the question. Raising a big stink just
because someone wants additional information about your question is
pointless at best and needlessly antagonistic at worst.
Pete