我正在创建一个基于缓存的数据阅读器,它将解析基于文本的文件并将内容加载到内部数据结构中。然后,在加载数据之后,可以通过各种方法访问数据。 reader类应该自动从构造函数中的磁盘加载数据吗?
using(CachedDataReader reader = new CachedDataReader(@"C:\someFile.txt")) // Load data now
{
string getValue = reader.GetValue(264);
}
或者我应该明确地使用Open / Read / Load方法来加载数据吗?
using(CachedDataReader reader = new CachedDataReader(@"C:\someFile.txt"))
{
reader.Load() // Load data now
string getValue = reader.GetValue(264);
}
或者,我可以在构造函数中添加一个可选的布尔参数来自动加载数据
public CachedDataReader(string filePath, bool autoLoad = true)
{
if(autoLoad)
Load();
}
答案 0 :(得分:1)
reader类应该在构造函数中自动从磁盘加载数据吗?
不符合Microsoft's design practices:
在构造函数中执行最少的工作。除了捕获构造函数参数之外,构造函数不应该做很多工作。任何其他处理的成本应该延迟到需要。
这可能是一个坏主意的一个实际原因是,如果您在加载数据之前必须设置的属性。如果你在构造函数中完成所有工作,那么实现它的唯一方法就是为每个可能的属性组合使用构造函数重载。
答案 1 :(得分:1)
从某种意义上说,我的答案是"不是,或两者都是"
正如D Stanley所写,构造函数不应该做任何实际的工作,更不用说磁盘I / O了。
单独的Load
方法可能很有用,人们似乎喜欢两阶段初始化,但这也意味着当您忘记加载数据时,您可以以不正确的半初始化状态访问该对象。
在GetValue
方法的情况下,考虑在您第一次访问数据时延迟加载数据。 BCL包含您可以使用的 Lazy<T>
。
结果可能如下所示:
class CachedDataReader
{
private readonly Lazy<YourLoadedData> data;
public CachedDataReader(string filePath)
{
// Prepare loading logic, but don't do anything yet.
data = new Lazy<YourLoadedData>(() => Load(filePath));
}
private YourLoadedData Load(string filePath) { } // Load your data here.
public string GetValue(int param)
{
// Access data.Value here to read cached data.
// The Load method will be called the first time only,
// all subsequent calls will use the cached value.
}
}
或者,您可以坚持使用单独的Load
方法并提供便利工厂方法来创建实例,设置必要的属性,调用Load
然后返回完全初始化的CachedDataReader
。