How to implement a "function" to be performed on an array in C#
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开发者_C百科 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!
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;
}
}
}
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)
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
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).
精彩评论