静态可变人口最佳实践
本文关键字:最佳 人口 变人 静态 | 更新日期: 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文件夹的情况下进行单元测试。