You have several options. None of them matches exactly what you want, but depending on what operations you need, you may come closer.
First, you should use the general method, in which the generic type is limited, but the only operations you can perform are limited:
public void Update<T>(T[] arr, int startIndex, int endIndex) : IComarable { if (condition1) { //Do some array manipulation } else if (condition2) { //Do some array manipulation } else if (condition3) { if (subcondition1) { //Do some array manipulation } } }
And the conditions and array manipulations in this function will be limited to expressions that use the following forms:
if (arr[Index].CompareTo(arr[OtherIndex])>0) arr[Index] = arr[OtherIndex];
This is enough to do things like finding a minimum or maximum or sorting elements in an array. He cannot do addition / subtraction / etc., Therefore, he cannot, say, find the average value. You can compensate for this by creating your overloaded delegates for any additional methods you need:
public void Update<T>(T[] arr, int startIndex, int endIndex, Func<T,T> Add) : IComarable {
You will need a different argument for each operation that you are actually using, and I donβt know how it will be performed (this last part will be the topic here: I have not tested any of this, but performance seems to be critical for this question).
Another option that came to mind is the dynamic type:
public void Update(dynamic[] arr, int startIndex, int endIndex) {
This should work, but for something repeating over and over again, as you say, I don't know what it will do with performance.
You can combine this option with another answer (now deleted) to return some type safety:
public void Update(float[] arr, int startIndex, int endIndex) { InternalUpdate(arr, startIndex, endIndex); } public void Update(double[] arr, int startIndex, int endIndex) { InternalUpdate(arr, startIndex, endIndex); } public void InternalUpdate(dynamic[] arr, int startIndex, int endIndex) {
Another idea is to double all the floats:
public void Update(float[] arr, int startIndex, int endIndex) { Update( Array.ConvertAll(arr, x => (double)x), startIndex, endIndex); } public void Update(double[] arr, int startIndex, int endIndex) {
Again, this will redistribute the array, and therefore, if this causes a performance problem, we will have to look elsewhere.
If (and only if) everything else does not work, and the profiler shows that this is a critical section of the performance of your code, you can simply overload this method and implement the logic twice. It is not ideal in terms of code maintenance, but if a performance problem is well established and documented, it may be worth a copy of the headache of pasta. I included a sample comment to indicate how you can document this:
public void Update(float[] arr, int startIndex, int endIndex) { //...logic here } public void Update(double[] arr, int startIndex, int endIndex) { //...logic here }
One final point to explore here is that C # contains a generic type of ArraySegment<T> , which may be useful for this.