由于传入对象可以是任意对象,不可能一一列举并特殊处理,所以乍一看,问题有些棘手,阅读了一些MS实践后找到了一个可以让更多类型的对象实现拷贝的方法,以下是思路:
- 如果传入对象是值类型,直接返回即可;这里可以通过Type.IsValueType来判断。
- 如果传入对象是IComponent,需要首先获取DesignHost,通过DesignHost创建IComponent的新实例,然后通过PropertyDescriptor对每个可以设置的属性做递归拷贝(由于代码量,这里没有列出对Component对象拷贝的代码)。
- 如果传入对象实现IClonable,采用Clone方式获得拷贝对象并返回。
- 获取传入对象的TypeConverter,尝试转换传入对象成InstanceDescriptor,如果传入对象允许转换成InstanceDescriptor,同时转换的InstanceDescriptor实例不为null,并且已经完成,调用InstanceDescriptor.Invoke获取拷贝对象。
- 如果3没有成功,如果传入对象允许转换成string并且允许从string转换成实例,尝试转换传入对象成string,在从string转换得出新对象。
- 如果4都失败了,检查传入对象的类型是否支持Serialize,通过Type.IsSerializable来判断;如果支持,首先Serialize传入对象到MemeryStream,然后通过Deserialize得到新对象并返回。
- 如果以上均失败,说明对象不支持Design-Time拷贝,直接返回。
1
private static object CopyValue(object value)
2
}
2