You mean type-classes? Scala and Haskel have them. It's certainly nice to be able to do statically type-checked stuff like:
list.sorted
list.max
list.sum
The problems with languages like C# (or Java) go beyond the lack of type-classes or similar. For example, given a type such as List<T>, you're restricted to define methods only "
for all T", as these languages don't allow you to define methods only "
for some T". Examples include methods such as "sorted" or "max", relying on type T implement some sort of Ordering interface, or "sum", relying on type T to be some sort of Number.
So even if you would have a way to specify that types X, Y and Z have implementations for this and that set of extension methods, it would still be of somewhat limited use, given that one wouldn't be able to also use this in code making heavy use of generics, much like how interfaces themselves aren't used much in code making use of generics, because code making use of generics is usually some dumb Container<T>, where almost nothing about T is known.
The best part about type classes is that you don't have to control/modify the type's implementation, in order to make it implement a certain type-class. Type-classes are like open interfaces. If the builders of C# never bothered to provide you with some common interface you want for built-in types, that's OK, because you can make one up.
Scala also has implicit conversions and "view bounds". Implicit conversions go beyond extension methods and View Bounds allow one to specify that some type X can be viewed as some type Y (either Y inherits from X, or there exists an implicit conversion from X to Y). Something like:
def sample[X <% Y](item: X) = item.callMethodFromY
But these are mostly useful for builtins and deprecated for general-purpose usage in favor of context bounds (type-classes). It's still nice that builtins such as Array[T] is
viewable as a Seq[T] and Strings are viewable (in true FP tradition) as sequences of chars, allowing one to do this:
"some string".map(_.toUpper) // => "SOME STRING"
What's interesting about the above example is that mapping over a string, produces a string, highlighting another Scala feature that goes beyond type-classes:
"some string".map(_.toString)
// => Seq(s, o, m, e, " ", s, t, r, i, n, g)
This is the CanBuildFrom pattern. See this awesome example from M. Odersky himself:
http://stackoverflow.com/a/1728140