日期:2014-05-17  浏览次数:21172 次

知道了Type,如何将object转换类型是该Type对象的实例??
假如我一个Type对象t,
然后有一个object o,
现在根据布尔表达式:t==o.GetType()
true:
则转换将o转换为类型为t的对象。
false:
无操作。

因为t是动态获取,可能任意类的Type对象,非固定某一类型。
因此无法如此:if(o is XXX)
也不是t.InvokeMember(...);因为这个转换是传输所必须的,我不需要它内部成员调用。

其实就是我写了一个公共方法,使用反射进行构造实例,并PropertyInfo.SetValue,我只知道传进来的Type对象,和一些其他参数(均为object),现在就判断假如存在一个集合属性(List<T>,只考虑这种集合),则需要根据参数构建List<T>(参数的实际引用并不一定是T也可能是T的派生类)
由于Type对象不固定,集合中的<T>也不确定,所以就犯难在这里了。

不求一定去解答题目中所问,能有更好的设计,我更加佩服。

------解决方案--------------------
类型是编译器识别的东西,如果你在写代码的时候知道类型,或者类型的基类,你可以直接用as或强制类型转换
比如
object o = 32;
IConverable c = o as IConvertable;
or
int c = (int)o;
如果这个类型在你写程序的时候没有,只好一直用反射了。在语法上你没有办法用一个类型和它关联。不过你可以用dynamic,其实它相当于反射,不过编译器不会检查这个对象是否合法,直接编译,比如
object o = new { id = 1, name = "a" };
dynamic d = o;
int i = d.id; // right
d.id = 3; // wrong, because its readonly
d.abcd = "aaa"; // wrong, not such a property
注意这些错误只能运行的时候发现。使用dynamic可以绕过编译器检查。
你也可以结合两者访问集合,比如
object o = ...;
foreach (dynamic d in o as IEnumerable)
{
    Console.WriteLine(d.Name);
}
(前提是o本身是一个List<T>)
------解决方案--------------------
曹版主说了那么多,讲了很多基础,其实楼主并未明白,你不可能将object按照Type对象转换成对应的类型对象。因为Type做为类型的模板,它本身可以通过InvokeMember方法(除此之外,还有其他多种反射创建实例的方法)来构造这种类型的实例对象并以object返回(为什么返回object?因为其一:虽然Type对象知道它描述的是哪种类型,但是方法返回却不可能指定为某一种类型,必然为所有类型的超集。其二:反射能够反射编译后的程序元数据文件中(元数据定义表),却不能访问(元数据引用表),所以你虽然知道是哪种类型,却不能找到类型指令,导致编译器无法调用类型指令(VS代码编辑器中的关键字以及类型名都属于编译器指令))。
虽然返回的是object,但是实际引用一直是Type对象所描述的类型对象。故在属性赋值时,只要object的实际引用的类型和属性的类型兼容(as 转换可成功,或者实现了转换重载等),必然会赋值成功。

实际上,你只需要System.Activator.CreateInstance(p.PropertyType),这样保证你赋值成功,记住,就目前来说,除非微软更新,否则永远不要考虑题目中的问题。