我有一个类Meterage,我希望可以多次实例化,可能会连续快速实例化。每个类都需要知道执行机器中dropbox文件夹的位置,我有这个代码。
该班级目前有一个变量:
private string dropboxPath = string.Empty;
保持路径,但我正在考虑将其作为静态来保存
的重复执行this.LocateDropboxFolder();
在构造函数中。但我对转换有点担心:如果两个构造函数同时尝试设置它会怎么样?构造函数中的此代码是否安全(在此示例中,LocateDropboxFolder也变为静态):
public Meterage()
{
if (dropboxPath == string.Empty)
{
LocateDropboxFolder();
}
}
我认为只要我不在多线程中进行构建,我的担忧可能就无关紧要了?
答案 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文件夹的情况下进行单元测试。