views:

130

answers:

6

Let's say I write a really kick-ass interface. So kick-ass, in fact, that I'd like some of the builtin types I use to implement them, so that whatever code I write that uses this interface can also use the builtin types.

public interface IKickAss
{
    int Yeahhhhhhh() { get; }
}

public static class Woot
{
    public int Bar(IKickAss a, IKickAss b)
    {
        return a.Yeahhhhhhh - b.Yeahhhhhhh;
    }
}

// What I'd like to do, sort of.
public partial struct Int32 : IKickAss
{
    public int Yeahhhhhhh
    {
        get
        {
            return this;
        }
    }
}

I've wanted this many times for many reasons. The most recent is that I've implemented radix sort for "uint", but have also created a simple "IRadixSortable" interface that requires the property "uint RadixKey { get }". This means that I've basically duplicated the sorting code: once for uint arrays, the other for IRadixSortable arrays. I'd rather just write one by making the uint type implement IRadixSortable. Is there some way to do this... maybe using reflection?

Haskell can do this (i.e. typeclasses can be instantiated on any data type at any time,) and I think that's one very important reason why it's so powerful. C# could really use this feature. Maybe call it "extension interfaces" :)

+2  A: 

Yes and no.

You're probably looking for Duck Typing, see the following article.

arul
Thanks for the link. I'll look into it later to how I can use it to solve my problem.
kinghajj
A: 

What about generics? The basic numeric types all implement ICopmarable, so you could write an IComparer implementation to pass to the array's Sort method.

Or perhaps an extension method.

Bill Wert
That's not useful because Radix Sort is a non-comparison sort, so using IComparable couldn't help much.
kinghajj
and the .net framework uses your comparer within its quicksort.
SnOrfus
+2  A: 

Not with interfaces, but you could do something similar using Extension Methods. You just wouldn't get the "contract"

Tim Jarvis
A: 

If you control creation of instances you can inherit from the class and implement the interface in the new inheritor class.

zvolkov
A: 

Others have answered the main question, but regarding your specific radix sorting scenario, you could also look at the kind of pattern used in the .NET Framework for comparisons, hashing, etc.: allow the user of your radix sort method to pass in an object that controls the sorting order. E.g. create an IRadixKeyProvider interface (analogous to IHashCodeProvider or IComparer) with a RadixKey property.

It's not ideal because users would have to pass in an IRadixKeyProvider each time they radix-sort a collection, rather than defining the radix key once and for all on the collection type. (Though you could probably mitigate this by creating an overload of your sort method for predefined types which created the relevant IRadixKeyProvider internally and then forwarded to the more general method.) And of course it doesn't address the more general scenario (yeah, I want typeclasses too!). But at least it saves you from duplicating the radix sorting code.

itowlson
A: 

I can't see a solution for intrinsic types, but for other types (ie. ones created by your or someone else) you could just subclass it and implement the interface of your choice.

public interface ISortable
{
    // ... whatever you need to make a class sortable
}

public class ExistingType
{
    // whatever
}

public class NewType : ExistingType, ISortable
{
    // ...
}

unless of course, if you have access to the existing type... then just have it implement your interface.

SnOrfus