views:

98

answers:

1

I'm trying to write an extension method that will add the function HasFactor to the class int in C#. This works wonderfully, like so:

static class ExtendInt
{
    public static bool HasFactor(this int source, int factor)
    {
        return (source % factor == 0);
    }
}

class Program
{
    static void Main()
    {
        int i = 50;
        int f = 2;
        bool b = i.HasFactor(f);
        Console.WriteLine("Is {0} a factor of {1}? {2}",f,i,b);
        Console.ReadLine();
     }
}

This works great because variable i in the Main() method above is declared as an int. However, if i is declared as an Int16 or an Int64, the extension method does not show up unless it is explicitly cast as an int or Int32.

I now would like to apply the same HasFactor method to Int16 and Int64. However, I'd rather not write separate extension methods for each type of int. I could write a single method for Int64 and then explicitly cast everything as an Int64 or long in order for the extension method to appear.

Ideally, I'd prefer to have the same extension method apply to all three types without having to copy and paste a lot of code.

Is this even possible in C#? If not, is there a recommended best-practice for this type of situation?

+3  A: 

No, this is not possible in C#. You'll have to create one extension method for each type. The closest is to have an extension method that operates on an interface, but in this case there is no INumeric interface or anything similar that is implemented by the various numeric types.

Eilon
Actually it is possible by some convoluted usage of Expression Trees (and/or dynamics if you're in .NET 4.0) - Check out Marc Gravel's answer to another SO question here: http://stackoverflow.com/questions/1987136/should-overloaded-methods-with-value-types-be-consolidated-into-a-generic-method/1987308#1987308, and his MiscUtil library.
Aviad P.
Well, the **operators** (`%` etc) can use this - but not the extension method code. So I think (+1) that Eilon has the truth of it. A number of very similar overloads are in the future, I suspect.
Marc Gravell
That's interesting. I'd be interested to know if `dynamic` (or some other .NET 4.0 feature) could be used to limit an extension method to specific types. Has this been done? (Perhaps this should be a separate SO question).
Ben McCormack
That's definitely an interesting idea. Though, I think even with dynamic, you'd want the type to implement IDynamicObject, which is of course not an option here since you don't own the types in question (int, long, etc.).
Eilon