在写一个wp的论坛程序时,我定义了几个类。一个是管理类(即Manager),这个管理类不能被实例化,它管理着论坛的板块类型(PlateCategory)和板块(Plate)的集合,即
static PlatesManager() {//…
private static ObservableCollection<PlateCategory> PlateCategories; private static ObservableCollection<Plate> Plates; public static ObservableCollection<PlateCategory> GetPlateCategories() { return PlateCategories; } public static ObservableCollection<Plate> GetPlates() { return Plates; } }
当然,这没什么,很正常不过,我又想,如果每次创建一个新的Plate和PlateCategory类都要调用一下这个Manager类的Add方法,感觉好像很麻烦,于是我就在Plate和PlateCategory的构造方法和析构方法中添加了如下代码:
public PlateCategory() { PlatesManager.AddPlateCategory(this); } ~PlateCategory() { PlatesManager.RemovePlateCategory(this); }
这个还好,我也自我感觉良好。不过比较诡异的一幕要发生了,我不知怎么地居然还想弄一个仓库类,觉得这样比较又逼格。于是创建了IRepository接口,并创建了两个仓库PlateRepository和PlateCategoryRepository。接口定义了增删改查操作:
public interface IRepository<T> { IEnumerable<T> GetAll(); T Get(T t); T Get(int id); T Add(T t); bool Remove(T t); bool Remove(int id); bool Update(T t); }
然后我把这两个仓库添加到了Manager管理类中,并写下了静态构造器,也成为类型构造器以及增删改查:
public class PlatesManager { static PlatesManager() { PlateRepo = PlateRepository.GetInstance(); PlateCateRepo = PlateCategoryRepository.GetInstance(); PlateCategories = PlateCateRepo.GetAll() as ObservableCollection<PlateCategory>; Plates = PlateRepo.GetAll() as ObservableCollection<Plate>; PlateCategories = new ObservableCollection<PlateCategory>() { new PlateCategory{Name="手机"}, new PlateCategory{Name="电脑"}, new PlateCategory{Name="手表"}, }; Plates = new ObservableCollection<Plate>() { new Plate("WP",PlateCategories[0]), new Plate("IOS",PlateCategories[0]), new Plate("Android",PlateCategories[0]) }; } public static void AddPlate(Plate plate) { PlateRepo.Add(plate); } public static void AddPlateCategory(PlateCategory plateCategory) { PlateCateRepo.Add(plateCategory); } public static bool RemovePlate(Plate plate) { return PlateRepo.Remove(plate); } public static bool RemovePlateCategory(PlateCategory category) { return PlateCateRepo.Remove(category); } public static bool RemovePlate(int fid) { return PlateRepo.Remove(fid); } public static bool RemovePlateCategory(int id) { return PlateCateRepo.Remove(id); } private static IRepository<Plate> PlateRepo; private static IRepository<PlateCategory> PlateCateRepo; }
看起来是不是一切over,但当我运行代码时,神奇的一幕出现了,抛出了一个TypeInitializationException异常,于是我找了很久错误,依然不知道什么原因,最后我翻开Jeff大神的CLR via C#,找到了静态构造方法的相关描述。
静态构造器会在第一次被调用时执行,也就是我调用Manager类时,Manager的静态方法开始执行,即初始化数据Plates集合和PlateCategories集合。执行这个任务时,静态构造器会调用一个线程和锁来确保数据不可被其他线程写,但这时,Plate和PlateCategory的构造器却调用了Manager类的Add方法,然而,Manager类是被锁起来的!因为他还没有被初始化完毕,所以就导致CLR抛出了一个异常,程序终止。5555~
然而,我为什么还要把仓库类给帮出来呢?好像并没有这个类什么事情,但其实并不是这样的。其实这个死并没有这么简单就作完。不过要表达的东西说完了,就不讲下去了,我才不会告诉你其实我一开始是在仓库中初始化数据呢╮( ̄▽ ̄)╭
献上哥特萝莉sama照片一张。。。