views:

136

answers:

4

Coming from a non-OO background in Matlab, I'm looking to perform some of the operations I am used to in a best-practice manner for C#.

I have a class, which imports data from a source, and formats it into, amongst other things, an array of ints. I am going to want to perform some operations on this array. To keep it simple, lets say I want to take the average of all the values. The way I see it, I have three options:

  • The array is part of MyClass, so I could extend MyClass to return the average of MyArray.double arrayAverage=MyClass.ArrayAve;
  • I could develop a static class, giving me access to the average by double arrayAverage= zotty.arrayMath.average(MyArray);

  • There is apparently some way in which I can inherit or interface so that I create a class specifically for performing such operations, which Id then be able to access by instantiating this new class, and passing it the array:

OperatorClass oc = new OperatorClass();

oc.data=MyClass.MyArray;

double arrayAverage = oc.ArrayAverage();

Extending the class seems risky, since it's also responsible for importing and formatting the data. I could become quite large if I add all the data processing to it too, and it wouldn't be straightforward for other people to add-to & work on alongside me.

Future code will require more complex operations on the array, and I've no idea what they will be at the moment. I will have use for some of the basic operations in future programs, which would be useful as part of the static class - the complex ones however would be redundant.

The separate class for performing the data processing allows the import/formatting class to remain isolated. It can provide both general and specific functions, but at the cost of instantiating another variable in the code, which seems to me to be a bit untidy.

I'd appreciate some input if you have thoughts on the matter!

+7  A: 

You can simply expose the array as IEnumerable<int> and then use any LINQ method, such as Average:

MyClass myObject = ...

double a = myObject.Data.Average();

where

class MyClass
{
    private int[] data;

    public IEnumerable<int> Data
    {
        get
        {
            return this.data;
        }
    }
}
dtb
+1. Also, any future operations that aren't directly supported by LINQ can be easily implemented using extension methods and used in a LINQ-alike way. For example, `double funkyResult = myObject.MyArray.FunkyFunction()` etc.
LukeH
Interesting... although since I'll be adding other situation-specific methods, would I be able to include them by extending the LINQ methods? Or would I add those to the main MyClass?
zotty
ah-ha! With extension methods, this sounds like an interesting option. Reading about them now...
zotty
While cute for many applications, I would not recommend designing libraries for scientific computing around LINQ. The cute to performance ratio will shrink quickly.
Scott P
This sounds like the way to go... thanks guys, much appreciated.
zotty
+1  A: 

You could write extension methods to do the processing that you want. This would put the processing in a different class from the data, and if your object hierarchy allows it will also allow the same methods to be used on other classes later. Note that if you go this path, you will need to provide enough information publicly for the extension methods to work (since they're not a part of the class, they can't access private or protected members).

Donnie
+2  A: 

A benefit in your first option (doing the work inside MyClass) is that you are not exposing the internal workings of the class to its clients. Let's say at some point in the future you decide you need to change the collection from an array to a generic List. Keeping the processing internal to the class means you will not need to hunt around and change other classes that have a tight dependency on how MyClass is implemented (like the OperatorClass)

Tim Trout
Good point, but in the current situation there's no chance that I'll want to change to a list... (famous last words..!)
zotty
+2  A: 

I highly recommend picking up this book from Didier Besset on creating object oriented numerical methods. The concepts have been very helpful to me over the years. Even though the examples are in Java, the code transfers easily to C#.

-Scott

Scott P
Thanks, I'll have a look at that.
zotty