利用 dot Net 技术中反射及代码发送的
动态退化或同步化接口封装
** 1 ** ** 技术背景 ** ** **
在“动态”这个词到处用的时代,怎样能够让程序真正的动态起来。
在 Java 的结构中我们看到了一个 java.lang.reflect 包,开始让程序能够了解程序的结构。然后作为 Java 的好徒弟 dot Net 框架中 System.Reflection 命名空间看到了 AssemblyBuilder , ModuleBuilder , TypeBuilder 及其它 *Builder ,而程序能够构造程序结构。我们进入了真正的动态运用的时代。
回想一下,这是多么令人震惊的功能啊!让我们运行动态生成的代码吧。如果你运行的不是原本硬盘上载入的代码,那是多大的飞跃啊!
** 1.1 ** ** 反射 ** ** **
反射是 dot Net 框架中的面向对象技术中的一个极为重要的部分。它由 System.Type 类和 System.Reflection 命名空间及其子空间中的所有类完成。在所有类的根类 Object 的实例方法 GetType() 可以得到描述实例的类信息的 Type 类实例。
反射的功能使得程序可以了解自身结构的手段,除此还可以提供动态构造程序集 (Assembly) ,模块 (Module) ,类 (Type) 结构的途径,使得原本僵死的程序有了活力。反射使得程序可以访问程序结构,构造程序结构。反射 (reflection 也称 retrospection) 的还可翻译为“自省”或“反省” 。
** 1.2 ** ** 代码发送 ** ** **
代码发送就是运行时向方法构造器发送操作码和参数,使得最终实现动态生成类。然后就可以使用需要的代码结构进行操作。
反射发送是一种“发送”操作码的强大技术。虽然今天的编译器速度很快,内存和处理器的速度也足够,但是在必须的时候能够触及这么核心底层的部分,确实是一件令人欣慰的事情。
** 2 ** ** 退化与同步化理论 ** ** **
** 2.1 ** ** 退化 ** ** **
由面向对象的继承性多态性使得编程模型呈现出一个扩展的发散的结构,在许多接口的应用中将会只用到部分的功能(这里一般指方法( Method ), dot Net 中还包括属性( Property )和事件( Event ))。那么对于其他的部分只好在实现时放出异常或不作任何操作。如此便出现了退化,也就是一部分功能的退化。举例来讲:
l Sysetm.Collections.IList 的 C# 语言声明:
public interface IList : ICollection, IEnumerable
{
int Add( object value );
void Clear();
bool Contains( object value );
int IndexOf( object value );
void Insert( int index, object value );
void Remove( object value );
void RemoveAt( int index);
bool IsFixedSize { get ; }
bool IsReadOnly { get ; }
object this [ int index] { get ; set ; }
}
要实现上面的 IList 接口的只读( Read Only )封装是,要求在一个只读的派生类中退化 Add, Clear, Insert, Remove, RemoveAt, this[]{set;} 这些方法或属性,并且 IsReadOnly 返回常量 true 。 然而如此只是文档的规则不能保证一个返回 IsReadOnly 为 true 的实例必然做好了 ReadOnly 退化。
这样的退化仅仅是文档内的约定,而更应该程序约束。在后面的动态封装中就介绍了标准的退化封装的手段。
** 2.2 ** ** 同步化 ** ** **
实现同步化封装一般对要封装的类或接口的所有方法重写,重写模版如下:
public override ReturnType A_Method()
{
lock ( this ._syncRoot)
return this ._target.A_Method();
}
在直接调用前后,要进行同步化操作进入对象和退出对象。这样实现的类就成为原有类或接口的同步化封装。由于在多线程的应用中经常用到同步化封装,这里不赘述其应用了。
** 3 ** ** dot Net ** ** 框架中的退化与同步化封装实现 ** ** **
ReadOnlyList 类是 Sysetm.Collections.ArrayList 类的私有嵌套类,是对 IList 接口的 ReadOnly 退化封装。
SyncList 类是 Sysetm.Collections.ArrayList 类的私有嵌套类,是对 IList 接口的同步化封装。
通过的两个静态方法可以获得相应的封装实例,下面是相关的部分 C# 声明:
l ArrayList 类的摘要声明:
public class ArrayList : IList, ICollection, IEnumerable, ICloneable
{
……
private class ReadOnlyList : IList
{ …… }
private class SyncIList : IList
{ …… }
public static IList ReadOnly(IList list)
{
if (list == null )
throw new ArgumentNullException( "list" );
return new ArrayList. ReadOnlyList(list);
}
public static IList Synchronized(IList list)
{
if (list == null )
throw new ArgumentNullException( "list" );
return new ArrayList.SyncIList(list);
}
}
l ReadOnlyList类的摘要声明:
private class ReadOnlyList : IList
{
internal ReadOnlyList(IList l)
{
this ._list = l;
}
private IList _list;
// 退化方法实现
public virtual int Add( object obj)
{
throw new NotSupportedException(Environment.GetResourceString( "NotSupported" ));
}
……
// 非退化方法实现
public virtual bool Contains( object obj)
{
return this ._list.Contains(obj);
}
……
public virtual bool IsReadOnly
{
get
{
return true ;
}
}
……
}
退化的方法例如 Add ,放出异常。非退化的方法例如 Contains ,直接调用。只有 IsReadOnly 特殊处理返回 true 。
l SyncList类的摘要声明:
private class SyncIList : IList
{
internal SyncIList(IList list)
{
this ._list = list;
this ._root = list.SyncRoot;
}
private IList _list;
private object _root;
public virtual int Add( object value )
{
lock ( this ._root)
return this ._list.Add( value );
}
……
public virtual bool IsSynchronized
{
get
{
return true ;
}
}
……
public virtual object SyncRoot
{
get
{
return this ._root;
}
}
}
同步化处理所有方法例如 Add 。只有 IsSynchronized 特殊处理返回 true , SyncRoot 特殊处理返回初始化时输入的异步根。
** 4 ** ** 动态封装模型 ** ** **
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 49.6pt; TEXT-INDENT: -1cm; mso-list: l1 level2 lfo1; tab