110,536
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
//需要引用 Json.net 的类库。http://www.newtonsoft.com/json 可以下载,也可以屏蔽代码中演示用的json解析部分
//using Newtonsoft.Json;
//using Newtonsoft.Json.Linq;
//using Newtonsoft.Json.Serialization;
using System.Reflection;
using System.Diagnostics;
namespace qq20662.WeiXin.Tests.Models
{
//IList反射的操作的演示,请查看标有 ?????? 的行次。
//IList反射不出 Add 方法。奇怪。
public class ReflectionIList
{
public void test1()
{
//如果普通生成可以这样:
AA a1 = new AA();
a1.Ap1 = "xx";
BB_1 b1 = new BB_1();
b1.Bp1 = 115;
BB_2 b2=new BB_2();
b2.Bp1 = 171;
//注意这里可以替换为其他实现了 IList接口的用户自定义类
a1.AaBb = new List<IBB>();
a1.AaBb.Add(b1);
a1.AaBb.Add(b2);
//如何通过反射生成 AA 的对象。
//当 AaBb 中无法确定使用那个具体类来实例化,允许直接使用BB_1
string jString = @"{
""Ap1"":""xx"",
""AaBb"":[{""Bp1"":115},{""Bp1"":171}]
}";
//假定已经把json全部解析完毕了。这几行可以屏蔽
//JObject jo = JObject.Parse(jString);
Debug.Print(typeof(AA).Assembly.GetName().Name); //这里可以得到 qq20662.WeiXin.Tests ,在每个人的项目中都不一样的,可以复制出来,下面要用的
Debug.Print(typeof(AA).FullName); //这里可以得到 qq20662.WeiXin.Tests.Models.AA ,在每个人的项目中都不一样的,可以复制出来,下面要用的
//假定可以用工厂模式从配置文件加载 AA 的 type fullname
object oa1 = Activator.CreateInstance(
Assembly.Load("qq20662.WeiXin.Tests").GetType("qq20662.WeiXin.Tests.Models.AA"));
//获取 oa1 的所有属性
PropertyInfo[] props =oa1.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) ;
foreach (PropertyInfo prop in props) {
//这里可以与json做匹配,看属性名是否符合。
//比较简单,就忽略了。
if (prop.Name == "AaBb") {
Type t2 = prop.PropertyType.GetGenericArguments().First(); //得到泛型中的类型,如 IBB
Type[] typeArgs = { t2 }; //生成泛型参数
//假定提供参数,可以用 List<> 来实现 IList 接口
Type algTypeGen = typeof(List<>); //生成列表
Type algType = algTypeGen.MakeGenericType(typeArgs); //生成具体的泛型列表。
object oAaBb = Activator.CreateInstance(algType);
//下面省略用反射获取 BB_1 类型的对象。基本根上面差不多,可以用工厂类根据json和预先设置的字符串来返回实例
BB_1 b3 = new BB_1();
b3.Bp1 = 9999;
MethodInfo addMethod = prop.PropertyType.GetMethod("Add");
//??????下面这行就比较奇怪了,按道理 IList的属性应该有 Add 方法,但是这里返回的是null,未获取到。
Debug.Print((addMethod == null).ToString()); //这里返回 true 表示没有add方法,奇怪。
MethodInfo[] ms = prop.PropertyType.GetMethods();
foreach(MethodInfo mItem in ms ){
Debug.Print(mItem.Name);
}
//??????上面循环的输出结果是下面这些。
//get_Item
//set_Item
//IndexOf
//Insert
//RemoveAt
//下面这行的返回值是 System.Collections.Generic.IList`1[[qq20662.WeiXin.Tests.Models.IBB, qq20662.WeiXin.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
//应该是对的,那 Add 方法到哪里去了? IList.Add 方法应该有的呀?
Debug.Print(prop.PropertyType.FullName);
}
}
}
}
public class AA
{
public string Ap1;
protected IList<IBB> _aaBb;
public IList<IBB> AaBb{
get{return _aaBb ;}
set { _aaBb = value; }
}
}
public interface IBB
{
int Bp1 { get; set; }
void Add();
}
public class BB_1 : IBB
{
public int Bp1 { get; set; }
public void Add() { }
}
public class BB_2 : IBB
{
public int Bp1 { get; set; }
public void Add() { }
}
}