我应该为缓存的数据读取器提供Load()方法吗?

本文关键字:Load 方法 缓存 数据 读取 我应该 | 更新日期: 2023-09-27 18:11:25

我正在创建一个基于缓存的数据阅读器,它将解析基于文本的文件并将内容加载到内部数据结构中。然后,在加载数据之后,可以通过各种方法访问数据。阅读器类是否应该在构造函数中自动从磁盘加载数据?

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();     
}

我应该为缓存的数据读取器提供Load()方法吗?

reader类是否应该在构造函数中自动从磁盘加载数据?

不符合Microsoft的设计惯例:

在构造函数中做最少的工作。构造函数除了捕获构造函数参数之外不应该做太多的工作。任何其他处理的成本应该延迟到需要的时候。

这可能是一个坏主意的一个实际原因是,如果您必须在加载数据之前设置属性。如果你在构造函数中完成所有的工作,那么唯一的方法就是为每个可能的属性组合使用构造函数重载。

从某种意义上说,我的答案是"两者都不是"。

正如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