1

Okay, I am way outside my comfort zone here and am struggling with new concepts but I hope I can make myself clear.
As I understand it, global variables are very bad in C# (and are dangerous in general) but I don't really want to get into that debate. After some research I am led to believe that Singletons can help. Please feel free to offer alternatives here if that is wrong with the situation I describe below.

What I am trying to do is create a dynamic multi-dimensional array which will contain numerical data. This matrix will be varying in size and must be created during runtime (I am pulling data from a logging device through a GUI).
What I see being a solution is to create a class which has a variable which can I can get and set but with a dynamic size.

public class mySingleton
{
    public static int dataSize { get; set; }
    public double[] dataSet = new double[dataSize] { get; set; }               
}

Something to this effect but obviously this is wrong and does not work. I have been trying to research how to initialize an array at runtime but cannot figure it out, but I also feel like I don't know which terms to search. Any help?

Community
  • 1
  • 1
tmwoods
  • 2,353
  • 7
  • 28
  • 55
  • 2
    Any reason you have to use an array instead of a `List`? (not that this will actually help with the singleton question) – Metro Smurf May 14 '13 at 19:43
  • Not really; it was an arbitrary decision. As I understand it there isn't that much difference, but an array is faster than a list? Again these are concepts outside my comfort zone - I am still learning. – tmwoods May 14 '13 at 19:46
  • @tmwoods Faster? Sure. But are you prematurely micro-optimizing? It sounds like it. I'd go with a list until there becomes a performance issue and the list turns out to be the bottle neck – Steve's a D May 14 '13 at 19:48
  • @tmwoods: Faster depends on what you want to use it for. If it's size is static, then yes. But if you ever need to resize, probably not. But as @Steve suggests, the advantages of working with `List` probably outweigh minor performance hits unless you find it to be a bottleneck. – Matt Burland May 14 '13 at 19:49
  • I actually do a have a performance issue. These data sets are in the range of gigabytes with some serious filtering, analysis and statistical representation with them. So far it hasn't been too much of an issue but I want to be pro-active with this. – tmwoods May 14 '13 at 19:49
  • Neither the code in the question nor any of the answers are a *multi-dimensional* dynamic array like the question wants. – Jesse C. Slicer May 14 '13 at 20:18
  • I left it as a single dimension to keep it simple. It's not too hard to extrapolate the concept to multi-dimensions. – tmwoods May 14 '13 at 20:20
  • Is the overhead of attempting to create a dynamic-size array using singletons faster than list? I'm thinking that is quite unlikely. You should probably use List if you need a dynamic size "array", That is what it is for. – Robert Noack May 14 '13 at 20:24

4 Answers4

3

What you probably want to do is use explicit (rather than implicit) backing fields so that you can add logic to your getter and setter. Something like this:

public class mySingleton
{
    private static int _dataSize;    // you might want to set this to some sensible default
    public static int DataSize 
    { 
        get { return _dataSize; }
        set 
        { 
            _dataSize = value;
            _dataSet = null;        // changing the size will implicitly clear the array - but you could write code to resize if you really wanted to
        }
    }
    private static double[] _dataSet;
    public static double[] DataSet 
    { 
        get 
        {
            if (_dataSet == null) 
            {
                _dataSet = new double[_dataSize];
            }
            return _dataSet;
        }
        // you can include a setter if you want to let the consumer set the dataset directly - in which case it should update the _dataSize field.
    }               
}
Matt Burland
  • 44,552
  • 18
  • 99
  • 171
2

You may want to initialize the array in response to the set method on your dataSize property. You won't be able to use the quick "autofill" properties ("get; set;"), but that way you will be able to initialize the data set as soon as a user sets the data size.

So something like this:

public class mySingleton
{
    private static int _dataSize;
    public static int dataSize { 
        get {return _dataSize;} 
        set {
            _dataSize = value;
            dataSet = new double[value];
        } 
    }
    public double[] dataSet { get; private set; }               
}

In general, to set a static property of a class, you can use a static constructor (http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx) or control the flow of access to the class/data in a way that you can set up the static members before someone else needs to use them.

nealyoung
  • 88
  • 5
1

You can create an array of dynamic size easily:

double[] array = new double[size];

size can be any arbitrary expression of type int. So your code would look like this:

class ArrayHolder { public static double[] Value; } //global state

//set the global state somewhere else in your code:
var size = DetermineSize();
double[] array = new double[size];
ArrayHolder.Value = array; //publish globally

After having initialized the array it is available in the entire program. Arrays are reference types so there is no needless data copying here.

Sidenote: Why would you prefer a singleton to a static variable? Often they have the same pros and cons (IOW no meaningful difference). In my example I just used a static variable.

usr
  • 168,620
  • 35
  • 240
  • 369
  • I cant really justify why I went that way beyond reading that singletons were the better method. I am sort of standing on shoulders here. – tmwoods May 14 '13 at 20:21
  • @tmwoods I completely get this. Just trying to guide you. – usr May 14 '13 at 21:21
0

I am not sure if a Singleton suits best for your approach, but anyway, here is a Singleton Implementation:

public class MatrixSingleton
{
    private static readonly MatrixSingleton instance = new MatrixSingleton();

    static MatrixSingleton() 
    {
    }

    private MatrixSingleton()
    {
        this.Data = new List<Tuple<double, double>>();
    }

    public static MatrixSingleton Instance
    {
        get { return instance; }

    }

    public List<Tuple<double, double>> Data;

}

and the using of it

MatrixSingleton matrixSingleton = MatrixSingleton.Instance;
matrixSingleton.Data.Add(new Tuple<double, double>(1.1, 2.2));

For more information about the Singleton pattern these links might help:

http://braindrivendevelopment.com/2013/05/04/simplify-singleton-pattern/

http://www.csharpindepth.com/Articles/General/Singleton.aspx

Kai
  • 1,953
  • 2
  • 13
  • 18