刚刚学习C#,觉得它与Delphi真的很相似,毕竟是同一个老爸创造的东西,所以相似也是十分正常的。
今天学习了使用 ConfigurationManager,这玩意的作用就是管理应用程序的设置了。一般用法就是
setting1 = ConfigurationManager.AppSettings["setting1"].ToString(); setting2 = ConfigurationManager.AppSettings["setting2"].ToString();
......
可以对应读出app.config中的配置内容,大概就是:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="setting1" value="settingvalue1"/> <add key="setting2" value="settingvalue2"/> ...... </appSettings> </configuration>
这个类是个好东西,方便程序员读取本地设置。但因为它太方便了,所以我曾经见过一些教程的示范代码是随用随读取,即是哪个地方需要配置了,就马上用上面的代码读取。我觉得这是十分低效的做法,我喜欢把所有的配置都放到一个基本设置类里面去的,一次读出,这样有效地控制程序模块间的不统一性以及读取文件的延时,如这样:
class BaseAppValueConf { public static string setting1 = ""; public static string setting2 = ""; ...... public static void initMe() { setting1 = ConfigurationManager.AppSettings["setting1"].ToString(); setting2 = ConfigurationManager.AppSettings["setting2"].ToString(); ...... } }
不知大家有没有这个感觉,写这种读取、写入配置的工作是一件低技术、重复、不好玩的事、而且费神费力的事。每写一个配置的名称就要重复写它的名字很多次(4次), 如果一个程序有个几十个设置,那就相当惹人烦,而且很容易错,所以我这样去做:
创建一个抽象的基类,把它放在一个公共的文件中,我自己就用 FlexAppSetting.cs,方便其它应用能共享:
using System; using System.Collections.Generic; using System.Linq; using System.Configuration; namespace FlexAppSetting { public abstract class CustomBaseAppValueConf { private static bool hasKey(string[] ak, string n) { for (int i = 0; i < ak.Count(); i++) { if (ak[i] == n) return true; } return false; } abstract public void initMe(); protected void _initMe(CustomBaseAppValueConf cbavc) { Type selfType = cbavc.GetType(); System.Reflection.FieldInfo [] fis = selfType.GetFields(); for (int i = 0; i < fis.Count(); i++) { string[] ak = ConfigurationManager.AppSettings.AllKeys; if (hasKey(ak, fis[i].Name)) { if (fis[i].FieldType.Name == "Int32") { int v; try { v = Convert.ToInt32(ConfigurationManager.AppSettings[fis[i].Name].ToString()); } catch (Exception) { v = 0; } fis[i].SetValue(selfType, v); } else { fis[i].SetValue(selfType, ConfigurationManager.AppSettings[fis[i].Name].ToString()); } } } } } }
然后在某个应用程序中,当要读取配置时,只要这样做就行了。
class BaseAppValueConf : CustomBaseAppValueConf { public static string setting1 = ""; public static string setting2 = ""; public static int nonSaveSetting = 2; ...... public static void initMe() { _initMe(this); ...... nonSaveSetting = 5555; } } .... BaseAppValueConf bavc = new BaseAppValueConf(); BaseAppValueConf.appPath = System.AppDomain.CurrentDomain.BaseDirectory; bavc.initMe();
这个CustomBaseAppValueConf 的作用就是对照着程序中的各设置值的名字,自动从app.config中读取出来,比原来要方便,而且不容易错,只要在程序中写一次变量名,在xml中再写一次就行了。
CustomBaseAppValueConf中用到了C#的反射机制,这是个好东西,与Delphi里的RTTI十分相似,但比Delphi的要强。
另外,希望各位前辈指正一下程序。总觉得 if (hasKey(ak, fis[i].Name)) 这句不应该这样写,但又没找到好的方法,所以就这样写了。
简化并统一 ConfigurationManager 的操作
原文:http://blog.csdn.net/flexitime/article/details/19708935