静态可变人口最佳实践

本文关键字:最佳 人口 变人 静态 | 更新日期: 2023-09-27 18:05:15

我有一个Meterage类,我希望它被实例化几次,可能是快速连续的。每个类都需要知道dropbox文件夹在执行机器中的位置,我有相应的代码。

类当前有一个变量:

private string dropboxPath = string.Empty;

保存路径,但我正在考虑将其设置为静态,以节省重复执行

this.LocateDropboxFolder();
构造函数中的

。但我有点担心的开关:如果两个构造器试图设置这个在同一时间?构造函数中的这段代码是否安全(LocateDropboxFolder在本例中也变为静态):

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

我认为我的关注也许是无关紧要的,只要我没有建设发生在多个线程?

静态可变人口最佳实践

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

private static string dropboxPath;
static Meterage()
{
    LocateDropboxFolder();
}

如果你不想重新分配字段,我建议你使用readonly修饰符,那么代码应该看起来像:

private static readonly string dropboxPath;
static Meterage()
{
     dropboxPath = LocateDropboxFolder();
}

LocateDropboxFolder在这种情况下需要返回一个字符串

构造函数外部声明的变量在构造函数之前求值。然后构造函数将对其求值。

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

如果您想要防止其他构造函数覆盖默认值,请尝试这样做:

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

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

static Meterage()
{
     LocateDropboxFolder();
}
private static LocateDropboxFolder()
{
    ...
}

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

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

在第二次构造函数执行时,LocateDropboxFolder()将不会执行,因为dropboxPath将不再等于string.Empty(前提是'LocateDropboxFolder()'不返回string.Empty

然而,如果LocateDropboxFolder()是异步的,或者对象是在不同的线程上实例化的,那么在LocateDropboxFolder()函数设置dropBoxPath之前创建第二个Meterage实例是可能的。因此,可能会对该函数进行多次调用。

如果您希望防止这样的多线程错误,您可以考虑使用锁语句。

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

另外,如果你在构造函数中设置dropboxPath的值,那么为它设置默认值是没有意义的。我只是声明它(而不是赋值它),然后在你的构造函数中检查null

我有一种感觉,你的Meterage类违反了单一职责原则。测量值与文件访问有什么关系?我想说你有两个关注点:你的Meterage和FolderLocator。第二个应该有一些属性或方法,如Dropbox,可以使用延迟评估模式。它应该被实例化一次,并且这个实例可以被注入到每个Metarage实例中。

也许不是FolderLocator但文件系统与一些更多的方法比只是一个单一的属性?不知道你到底在干什么。无论如何,为它做一个接口。这样就可以在不使用实际Dropbox文件夹的情况下进行单元测试。