Type^ t=List<>::typeid;
VS总是提示List缺少类型参数,不过像下面这样子是可以的:
Type^ t2= List<IUserInfo>::typeid;
但是IUserInfo 类型正是我们要动态反射的,事先并不知道,所以一时不知道在C++/CLI中如何构建List泛型的具体实例,MS你不能这么坑好么?
既然无法直接解决,只好曲线救国了,通过类型名字,来创建类型:
String^ listTypeName = System::String::Format("System.Collections.Generic.List`1[{0}]", interfaceType->FullName);
可惜,这种方式不成功,只好一步步来了,先创建基本的List泛型类型:
String^ listTypeName = "System.Collections.Generic.List`1";
Type^ listType = System::Type::GetType(listTypeName);
成功,在此基础上,创建真正的泛型List对象实例就可以了,完整代码如下:
static Type^ CreateGenericListType(Type^ interfaceType)
{
//直接这样创建泛型List不成功:
// String^ listTypeName = System::String::Format("System.Collections.Generic.List`1[{0}]", interfaceType->FullName);
String^ listTypeName = "System.Collections.Generic.List`1";
Type^ listType = System::Type::GetType(listTypeName);
Type^ generListType = listType->MakeGenericType(interfaceType);
return generListType;
}
static IList^ CreateGenericList(Type^ interfaceType)
{
Type^ generListType = CreateGenericListType(interfaceType);
Object^ listObj = System::Activator::CreateInstance(generListType, nullptr);
IList^ realList = (IList^)listObj;
return realList;
}
在方法 CreateGenericListType得到只是一个泛型List的类型,但我们并不知道这个List具体的形参类型,所以这个泛型List还是无法直接使用,幸好,泛型List也是继承自非泛型的IList接口的,所以在 CreateGenericList 方法中将泛型List对象转换成IList接口对象,之后就可以愉快的使用List对象了。
IList^ realList = CreateGenericList(interfaceType);
realList->Add(CurrEntity);//CurrEntity 是interfaceType 类型的动态实体类
反射静态方法
在上一篇中,我们在一个.NET方法中通过接口动态创建实体类,用的是下面的方式:
IUserInfo userinfo= EntityBuilder.CreateEntity<IUserInfo>();
CreateEntity是EntityBuilder的静态方法,现在我们需要在C++/CLI中,反射调用此方法。
为什么要反射创建实体类?
因为CreateGenericList(interfaceType) 创建的是一个泛型List对象,要求它的成员是一个实体类。
Object^ CreateEntityFromInterface(Type^ interfaceType)
{
MethodInfo^ method = this->entityBuilderType->GetMethod("CreateEntity", BindingFlags::Public | BindingFlags::Static);
MethodInfo^ genMethod = method->MakeGenericMethod(interfaceType);
Object^ entity = genMethod->Invoke(nullptr, nullptr);
this->CurrEntity = entity;
return entity;
}










