views:

212

answers:

4

Hello, I am recently working on a C# class library implementing an algorithm. The point is that I would like the users of the library to be able to choose the machine precision (single or double) the algorithm should operate with, and I'm trying to do it with generics. So, for instance:

    Algorithm<double> a = new Algorithm<double>();
    /** Some initializations here */
    double result = a.Solve();

or

    Algorithm<float> a = new Algorithm<float>();
    /** Some initializations here */
    float result = a.Solve();

Thus, the type parameter for the generic classes is meant to be a decimal number (because in the algorithm code I need to use +, *, /, -), but I don't know which kind of type constraint to impose on it. I have thought about building an interface with all the operators but, unfortunately, this is not allowed. Any ideas?

Otherwise, is it possible to obtain in C# something similar to template specialization in C++?

Thank you

Tommaso

+6  A: 

You can't, basically. The CLR type system doesn't support that kind of constraint.

I've previous blogged about how we could describe such constraints using "static interfaces" but I don't know of any plans to do anything similar.

You might want to look at the MiscUtil generic operator support which would let you use the operators - but you'd have to use a constraint of just struct or something like that, which would of course allow things like Guid which you don't want.

Jon Skeet
Another possibility, rather than defining interfaces and classes implementing them, you should be able to declare interfaces and list the classes that implement them in the interface declaration. The compiler should take care of the rest
devio
@devio: sounds like an interesting variant. Can you give some references?
tunnuz
@tunnuz there is no "reference", it's a wish, just as Jon's idea, and should be on somebody's wish list for the next C# version ;)
devio
Ah ok! :) I thought it was already possible to use it :)
tunnuz
+1  A: 

The closest match is value type constrain.

C# allows only three types of constrains

  1. Derivation Constrain
  2. Constructor
  3. Reference/Value type.

For complete documentation refer MSDN:
http://msdn.microsoft.com/en-us/library/ms379564(VS.80).aspx#csharp_generics_topic4

Guru
A: 

You could use a workaround: Define a method for every type you want to suport

private static Add(float a, float b) 
{return a+b;}  
private static Add(dluble a, dluble b) 
{return a+b;}  
...

and create a delegate for the right one at runtime:

MethodInfo addMethod=this.GetType().GetMethod("Add",BindingFlags.NotPublic|Static,null,new Type[2]{typeof(T),typeof(T)},null);  
Func<T,T,T> addFunction=(Func<T,T,T>)Delegate.CreateDelegate(typeof(Func<T,T,T>),addMethod);
Floste
A: 

This is generally a seriously fugly hack, but you can create a generic "wrapper" class for numeric types that exposes the operations you need and prevents instantiation using a non-supported value type (i.e. char), and then specify that the generic type parameter of your algorithm must be the wrapper class.

I like the workaround Floste posed in every respect except code duplication. You could even make it simpler; specify private method overloads, then one public generic method that will simply call the private method, and the runtime will pick the correct one (be sure to include a catch-all that throws a NotImplementedException).

KeithS