mercredi 20 janvier 2016

C# generic operators - RTTI approach

I intend to ask about generic operator+ overloading but not in typical "can I do operator+ for generic type" way.

Questions are on the bottom

I recently started to create matrix class in C# and after a while It came to me that I cannot do simple T + T !

Thus, I googled and googled and found several workarounds.

  1. Create Expression link
  2. Create abstract class abstract class Matrix<T>{//some code}. Create 'protected virtual method Add(T itemToAdd)' and then create operator like this : T operator+(T item1, T item2){return item1.Add(item2);}(most posts on stack) and then inherit this method in class Matrix : Matrix<int> here
  3. Use method Add such as : T Add(T first, T second){ dynamic output = first + second; return output;} (somewhere on stack)

First one just does not suited me so I tried second one but then I run onto serious problems like:

  1. (A LOT of )repetative code - I created 4 classes for : int, double, long, Complex - my own type
  2. Creating multiple extension methods and so on.

Third one is just so unsafe that I rejected it immidietlay.

After my struggling I came to realise : 'Why don't I use RTTI and reflection?' I know, it is expensive in running time but why not use static constructor to do this?

Here is my idea (pseudocode):

class Matrix{
   static Func<T,T,T> Add;
   static Matrix
   {
     if(T is int) 
        Add = (first,second) = > ((int)first)+((int)second);
     else if(T is long) 
        Add = (first,second) = > ((long)first)+((long)second);
   // and so on for built-in types
   else
   { // T is not built-in type
     if(typeof(T).GetMethods().Contains("op_Addition"))
     {
       Add = (first,second) => typeof(T).getMethod("op_Addition").invoke(first,second);
     } 
   }
}

I know that reflection is costly but it will do it only one time (per type)! And before you start argue : I am going to code T is int like this :

var type = typeof(T);
if(type==typeof(int)) // code

I am aware that I cannot explicitly convert T to int but there must be some sort of 'work around'. Problem is that (for example) Int32 has not explicit 'method' for operator+ hence, reflection is not of much use.

After all that introduction I have two questions :

  1. Is it a good approach or do you see major flaws in it?
  2. Is it doable? I don't want to start creating code without knowing for sure that my lambda function WILL work.




Aucun commentaire:

Enregistrer un commentaire