最近在开发字典,这个命题其实也不是从开发字典开始想到的,由来已久的问题,只是以前没有太在意,现在觉得接口里面静态方法虽然可以用其他方案代替,不过总觉得有些不爽。
考察一下下面这样的一个场景:
所有字典都有差不多的属性,例如字典名称,字典类型,使用的数据库等等:
/// <summary> /// Summary description for Dictionary /// </summary> public class DictEntry{ /// <summary> /// 数据库 /// </summary> public DBHelper.enmDBName DataBase; /// <summary> /// 字典类型 /// </summary> public DictionaryManager.DictionaryType DictType; /// <summary> /// 启用标志 /// </summary> public Boolean Enable; /// <summary> /// 单词名称 /// </summary> public String DictionaryTitle; /// <summary> /// 单词来源 /// </summary> public String Author;} 下面看看每本字典的方法:
我们可以查询字典获得一个HTML字符串的结果,也可以获得一个自定义类得结果集。当然这些行为是每种字典都应该有的共同行为,同时,按照我的设计,应该都是静态的。可能是我学习的不够,我认为静态的方法就是那些不依赖于具体实例,一个类固有的方法:那么我的接口应该是这个样子的:
public interface IDictEntry < T > { void GenerateHtml(List < T > SearchResult, GenerateInterface mGenerateInf); List < T > GetResultByKeyword(String KeyWord); T GetResultByID(String ID);}
这里的泛型T是每种字典的检索结果,是一个自定义的类型。
到这里一切都没有什么问题,下面看看具体的类吧:
using System; using System.Collections.Generic; using System.Web; using System.Data.OleDb; using System.Data; using System.IO; using System.Xml.Serialization; /// <summary> /// 中日词典 /// </summary> [Serializable] public class CEDictResultEntry{ public String SimpleChinese = String.Empty; public String TrandtionChinese = String.Empty; public String PinYin = String.Empty; public String PinYinExtend = String.Empty; public String English = String.Empty; /// <summary> /// 序列化 /// </summary> /// <param name="filename"></param> public void Save(String filename) { FileStream fs = null ; fs.Close(); } /// <summary> /// 反序列化 /// </summary> /// <param name="filename"></param> /// <returns></returns> public static CEDictResultEntry load(String filename) { FileStream fs = null ; return t; }} /// <summary> /// Summary description for CEDict /// </summary> public class CEDict : DictEntry,IDictEntry < CEDictResultEntry > { /// <summary> /// 根据关键字获得结果 /// </summary> /// <param name="strKeyWord"></param> /// <returns></returns> public List < CEDictResultEntry > GetResultByKeyword(String strKeyWord) { List < CEDictResultEntry > result = new List < CEDictResultEntry > (); OleDbConnection mConnection = DBHelper.GetConnection(DBHelper.enmDBName.CEDict); try { return result; } /// <summary> /// 生成HTML页面结果 /// </summary> /// <param name="SearchResult"></param> /// <param name="mGenerateInf"></param> public void GenerateHtml(List < CEDictResultEntry > SearchResult, GenerateInterface mGenerateInf) { if (SearchResult.Count == 0 ) { return ; } mGenerateInf.strSearchResult.AppendLine( " </ul> " ); } public CEDictResultEntry GetResultByID( string ID) { throw new NotImplementedException(); }}
GetResultByKeyword方法和 GenerateHtml不能是静态的方法。 换句话说,它们必须是某个实例才能使用的方法,这个和设计的本意相反,它们应该是固有的,类似于工具类的方法。
刚才找出了博客园的老前辈的一篇文章,里面有这么一段令人回味:
:
接口是包含一组虚方法的抽象类型,其中每一种方法都有其名称、参数和返回值。接口方法不能包含任何实现,CLR允许接口可以包含事件、属性、索引 器、静态方法、静态字段、静态构造函数以及常数。但是注意:C#中不能包含任何静态成员。一个类可以实现多个接口,当一个类继承某个接口时,它不仅要实现 该接口定义的所有方法,还要实现该接口从其他接口中继承的所有方法。
我使用接口的原因是为了能够
1.将字典作为即插即用的统一管理的部件
2.让编译器告诉我缺失的方法
C#不能使用静态接口的原因,可能在深层次的方法表,对象继承结构中,可能造成歧义的原因。但是,如果用设计角度说,我无法理解为什么不能有静态方法。
我也不知道有什么好的方法来解决这个问题。。。。。