使用Singleton的动态长度数组

本文关键字:数组 动态 Singleton 使用 | 更新日期: 2023-09-27 18:13:27

好吧,我已经走出了我的舒适区,正在努力理解新的概念,但我希望我能把自己说清楚。
据我所知,全局变量在C#中是非常糟糕的(并且通常是危险的),但我真的不想进入辩论。经过一些研究,我相信Singletons可以帮助。如果我下面描述的情况是错误的,请随时提供替代方案。

我要做的是创建一个动态多维array,它将包含数值数据。这个矩阵的大小是不同的,必须在运行时创建(我通过GUI从日志设备提取数据)。
我看到的是一个解决方案是创建一个class,它有一个变量,我可以getset,但具有动态大小。

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

有这样的效果,但显然这是错误的,不起作用。我一直在努力研究如何在运行时初始化数组,但无法弄清楚,但我也觉得我不知道要搜索哪些术语。任何帮助吗?

使用Singleton的动态长度数组

您可能想要做的是使用显式(而不是隐式)支持字段,以便您可以向getter和setter添加逻辑。像这样:

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.
    }               
}

您可能希望初始化数组以响应dataSize属性上的set方法。您将无法使用快速的"自动填充"属性("get;设置;"),但这样一来,一旦用户设置了数据大小,您就可以初始化数据集。

所以像这样:

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; }               
}

一般来说,要设置类的静态属性,可以使用静态构造函数(http://msdn.microsoft.com/en-us/library/k9x6w0hc(v=vs.80).aspx)或控制对类/数据的访问流,以便在其他人需要使用静态成员之前设置它们。

你可以很容易地创建一个动态大小的数组:

double[] array = new double[size];

size可以是int类型的任意表达式。所以你的代码看起来像这样:

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

初始化数组后,它在整个程序中可用。数组是引用类型,所以这里没有不必要的数据复制。

旁注:为什么你更喜欢单例而不是静态变量?通常它们有相同的优点和缺点(但没有意义的区别)。在我的例子中,我只是使用了一个静态变量

我不确定单例是否最适合您的方法,但无论如何,这里是一个单例实现:

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;
}

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

有关Singleton模式的更多信息,这些链接可能会有所帮助:

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

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