views:

281

answers:

4

Suppose I want to write a function like the following (as usual, a trivial example for illustrative purposes):

Public Function calcSqSum(Of T)(ByVal list As IEnumerable(Of T)) As T
    Dim sumSq As T

    For Each item As T In list
        sumSq += (item * item)
    Next

    Return sumSq
End Function

As you can probably guess, this function causes an error because a generic object is not guaranteed to implement the + operator. As far as I know, though, any numerical type (Integer, Double, Decimal, etc.) will.

Is there a way to write a (quasi-)generic function that can accept any numerical type, without having to explicitly overload the function for every such type yourself?

Alternatively, I suppose an equally acceptable solution would be to somehow check if a type implements the '+' operator (or any operator generally associated with numerical types and used by the function).

+7  A: 

No, since there's no specific common interface that all of them implement. In essence, there's no real notion of "numerical types" in the framework. Unless you wrap them in self-defined classes and have your method accept only your types (which is not really a direct answer to your question, just a workaround).

Mehrdad Afshari
Couldn't have put it better myself.
Garry Shutler
That's what I suspected... does this also mean, then, that there is no way to accomplish my secondary idea -- to check if a class implements a particular operator?
Dan Tao
It's possible to check for a particular operator *at runtime* but not as a compile time generic constraint. Nothing like "where T.operator+" is possible.
Mehrdad Afshari
Btw, if you want to prevent wrapping, you might make the class more flexible (remove the constraints) and blindly call operator + using reflection (essentially, duck typing). I'm sure I've seen an implementation of a calculation class that does this on SO. Search for it.
Mehrdad Afshari
+1  A: 

You can check this article: Using generics for calculations

mucit
A: 

Sorry you can't unless you create your own number class.

public static T Add<T> (T x, T y) where T: MyNumberClass
{ 
// your add code
...
}

The reason is that .NET only lets you constrain a generic method with a class or an interface.

Khalid Abuhakmeh
Oh and if you don't want to create your number class, you could always just do the constraint checking inside the generic method itself. You won't have compile time errors like the "where" syntax but it will throw runtime exceptions.
Khalid Abuhakmeh
A: 

You can use lambda expressions, like this:

        static T Add<T>(T a, T b)
    {
        // declare the parameters
        ParameterExpression paramA = Expression.Parameter(typeof(T), "a"),
            paramB = Expression.Parameter(typeof(T), "b");
        // add the parameters together
        BinaryExpression body = Expression.Add(paramA, paramB);
        // compile it
        Func<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
        // call it
        return add(a, b);
    }

It will not be typesafe, but it will work for types that has the expected operator (addition, in the example above).

Sergiu