静态变量人口最佳实践

时间:2014-05-27 10:07:37

标签: c# static

我有一个类Meterage,我希望可以多次实例化,可能会连续快速实例化。每个类都需要知道执行机器中dropbox文件夹的位置,我有这个代码。

该班级目前有一个变量:

private string dropboxPath = string.Empty;

保持路径,但我正在考虑将其作为静态来保存

的重复执行
this.LocateDropboxFolder();

在构造函数中。但我对转换有点担心:如果两个构造函数同时尝试设置它会怎么样?构造函数中的此代码是否安全(在此示例中,LocateDropboxFolder也变为静态):

public Meterage()
{
     if (dropboxPath == string.Empty)
     {
         LocateDropboxFolder();
     }
}

我认为只要我不在多线程中进行构建,我的担忧可能就无关紧要了?

5 个答案:

答案 0 :(得分:4)

如果字段是静态的,那么静态字段初始化器或静态构造器是初始化它们的简单方法。这将以线程安全的方式最多执行一次。

private static string dropboxPath;

static Meterage()
{
    LocateDropboxFolder();
}

如果您不想重新分配字段,我建议您使用readonly修饰符,那么代码应如下所示:

private static readonly string dropboxPath;

static Meterage()
{
     dropboxPath = LocateDropboxFolder();
}
在这种情况下,

LocateDropboxFolder需要返回一个字符串。

答案 1 :(得分:2)

在构造函数之前计算在构造函数外部声明的变量。然后构造函数将对其进行评估。

请记住,您最终只会有一个dropBoxPath。如果是这样的话,可以这样做。 (可选)使LocateDropboxFolder成为静态方法,并从static构造函数中调用它。

如果要阻止其他构造函数覆盖默认值,请尝试以下操作:

 if (string.IsNullOrEmpty(dropboxPath))
 {
     LocateDropboxFolder();
 }

或者,在static构造函数中(最多调用一次):

static Meterage()
{
     LocateDropboxFolder();
}

private static LocateDropboxFolder()
{
    ...
}

答案 2 :(得分:1)

如果您的代码同步执行,您的示例将是安全的。如果创建了多个实例,则将按创建它们的顺序调用它们的构造函数。

在第一次运行时,LocateDropboxFolder()将执行。完成后,将设置dropboxPath

在第二个构造函数执行时,LocateDropboxFolder()将不会执行,因为dropboxPath将不再等于string.Empty(提供' LocateDropboxFolder()'不返回{{ 1}}。

但是,如果string.Empty是异步的,或者对象在不同的​​线程上实例化,则可以在LocateDropboxFolder()设置Meterage之前创建第二个dropBoxPath实例。功能。因此,可能会多次调用该函数。

如果您希望防范此类多线程错误,可以考虑使用lock statements

答案 3 :(得分:0)

如果对象尝试从多个线程中连续多次构造对象,则可能最终会多次运行LocateDropboxFolder。只要该方法每次返回相同的结果,虽然这不应该是一个问题,因为它仍将使用相同的值。

此外,如果您在构造函数中设置dropboxPath的值,则无法为其设置默认值。我只是声明它(而不是分配它),然后在构造函数中检查null。

答案 4 :(得分:0)

我觉得你的Meterage课程违反了单一责任原则。有关文件访问的计量方法是什么?我会说你在这里有两个问题:你的Meterage,比方说,FolderLocator。第二个应该有一些属性或方法,如Dropbox,可以使用惰性评估模式。它应该被实例化一次,并且可以将这个单个实例注入每个Metarage实例。

也许不是FolderLocator而是FileSystem有一些方法而不仅仅是一个属性?不确定你在做什么。无论如何 - 为此创建一个界面。这样就可以在不使用实际的Dropbox文件夹的情况下进行单元测试。