your methods should be specific to a task. So if you are passing more than the expression you are doing too much in your method.
But if all your method needs is the evaluation of the expression, you can do something like this:
MyMethod(...,...,..., ProcessExpression(l,op,r),...)
Now the signature for this would be ProcessExpression( object l, string op, object r)
First thing to do is throw an exception if l.GetType() != r.GetType()
Also you need to look deep if it is an array and throw an exception if the array types are not equal.
Next you want to break up the process as two methods:
InternalProcess( object l, string op, object r) -AND-
InternalArrayProcess( IList l, string op, IList r )
Inside the latter process you just are iterating through each element in the array and calling InternalProcess(l[index], op, r[index])
You still have to do a case statement by types but you should only have to do it for the specific types you are working with on the first operand.
First, thank you for your comments, and sorry for my late reply.
In my project I am making my own custom math class, and I am currently working on methods for simple arithmetics on arrays. I need to perform math operations (+-/*) on array-to-array and array-to-variable. Also, and this is where my question fits; I would like to be able to add conditions on which the calculations will be done.
An example:
Say I have three arrays; A(10), B(10), C(10), all double.
Arrays A and B is to be added element by element, but only on elements where array C < 1 (for the same index number).
Another example:
Same as above, only B is a simple variable and not an array. B should then be added to A on all of A's elements where the corresponding value of C is less than 1.
My initial attempt was to throw all of this into one method, giving me too many alternatives on how to perform the calculations. My method took two arguments for the arrays to be added (A, B), as well as an expression for the conditions. The expression taken could be some sort of string like "if C < 1", or ideally even more complex variants; "if (C+A)/B < B+1". However, I found that parsing and executing such a string was not a simple task (to me!), so I lowered my aim and put three more arguments in my method; A left side (C), an operator string ("<") and a right side (1). As both sides could be either a variable or an array, and of datatypes double or datetime, and the operator could be of six types, I get 4 possibilities on the left side (double variable, double array, datetime variable, datetime array), 4 on the right side and 6 operator types. 4*4*6 = 96 possibilities (not 48 like I miscalculated in my initial post)
In stead of throwing all the code in one big method, I could overload it for different data types (double/datetime) and container types (variable/array), but that leaves me with exactly the same amount of code to maintain. It's just chopped up differently. And one could argue that it's actually simpler to keep it all in one massive method as then you have all the code in one place. If you need to do changes to the code at a later stage, you're sure you don't forget to update any of the overloads.
One simplification I was hoping to achieve was to pass the operator as an operator object of some sort, which could be included directly in the mathematical expression ( C(i) 'op' 1 ). This is possible in other languages like macro programming in SAS (if any of you have been in contact with that). Is it in .NET? Or does there exist some other way of achieving the same effect?
The closest to a solution I've gotten so far is to create my own data classes, and then overload the operators of the classes to perform the calculations the way I wanted them. This would actually be an excellent solution, had it not been that passing arguments to such overloads can only be done by value, not by reference. Testing showed that the performance of such a class was less than half of what could be achieved using a method taking a reference as arguments. As some of these calculations will run for hours and days, halving performance feels like a big concession to make.
Sorry if this was too verbose, just trying to explain what I'm trying to achieve.
Usually what I do when faced with a problem like this is to try and figure out ways of accomplishing this by working it out in a dummy class that I keep changing til I get the results.
What I don't believe you need, though, is passing values by reference. Passing by value is fine as long as you return the specific values needed.
You could try generics, for example, to see if that buys you anything. And play further with the overloads.
Have your methods become an iterative return so your IList method signature does numerous Answer<t>.Add( Compute( listA, op, listB))
Beyond that, I really don't have the time to think deeper on this problem. Try different things based on what I listed in my first answer and expand upon it until you get the best answer.
In the model I presented, making each call return a value (either the original object type or an element in an array) you never have to be concerned with how the data is being passed to you. Becoming dependant on reference values is at best risky, and possilbe dangerous. On the other hand, by returning the answer as an IList you give the caller the flexibility to a) leave the original arrays alone -or- b) assign one of the arrays to the answers returned.