这里写一下个人对.Net下反射技术的理解:
第一部分:个人讲讲反射
反射机制是一种运行时获取类(Type对象)和动态调用对象的成员的机制。
a.可以获取有关已加载的程序集和在其中定义的类型(如类、接口和值类型)的成员信息;
b.可以使用反射在运行时创建指定类的对象,以及调用和访问这些对象的成员。
这种动态获取的信息以及动态调用对象的方法的功能称为反射机制。
比如在myReflect.UI下定义了一个MyLyfeng类:
public class MyLyfeng
{
//无参构造函数
//有参数构造函数
public MyLyfeng(string name)
{
this.name = name;
}
//私有字段
private int beautyNum;
public int BeautyNum
{
get { return beautyNum; }
set { beautyNum = value; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
//带返回值无参数公共方法
public string SayName()
{
//逻辑
return null;
}
//无参数无返回值私有方法
private void Sleep()
{
//逻辑
}
//有参无返回值
public void SayHello(string name)
{
//逻辑
}
//有参数有返回值
public string ReturnParam(string param)
{
return param;
}
}
1.一般情况想要得到MyLyfeng类的实例对象,那么只需要一句代码:
//MyLyfeng lyf = new MyLyfeng() { BeautyNum=100};
MyLyfeng lyf2 = new MyLyfeng("My");
除了以上使用new的方法之外,还可以使用Reflection技术对MyLyfeng类进行操作.
2.本地动态创建
Type type=typeof(MyLyfeng);//本地可以访问到MyLyfeng类
//无参构造函数
object obj=Activator.CreateInstance(type);
//有参构造函数
ConstructorInfo c= type.GetConstructor(new Type[]{typeof(string) });//构造函数的实参类型
c.Invoke(new object[] { "name"});//实参
//公共的
//字段操作
FieldInfo field= type.GetField("name");
field.GetValue(obj);//obj.field
field.SetValue(obj,"Lyfeng");
//属性操作
PropertyInfo property =type.GetProperty("BeautyNum");
property.GetValue(obj, null);//obj.BeautyNum
property.SetValue(obj, 101,null);
//私有的
//字段操作
FieldInfo[] fields =type.GetFields(BindingFlags.NonPublic);
foreach (FieldInfo item in fields)
{
}
//属性操作
PropertyInfo[] propertys = type.GetProperties(BindingFlags.NonPublic|BindingFlags.Instance);
foreach (PropertyInfo item in propertys)
{
}
//方法操作
//无参无返回值
MethodInfo method=type.GetMethod("Sleep");
method.Invoke(obj, null);
//有参无返回值
MethodInfo method1 = type.GetMethod("SayHello");
method1.Invoke(obj, new object[] { "name"});
//无参有返回值
MethodInfo method2=type.GetMethod("SayName");
object returnValue=method2.Invoke(obj,null);
//有参数又返回值
MethodInfo method3=type.GetMethod("ReturnParam");
object ReturnValue=method3.Invoke(obj,new object[]{"param"});
//接口操作
//判断当前type是否实现IHarry接口
typeof(IHarry).IsAssignableFrom(type);
以上是一些比较的常用用法的列举,但是,在实际开发中我们可能并不能直接访问到MyLyfeng,那么需要进行一小点的改动,代码如下:
3.异地动态创建
假设在另一个类库IFrancis中有一个Francis类,在myReflection.UI下不能访问到它,我们只需要将IFrancis.dll生成到(或者复制一份到myReflection.UI到bin下),
然后使用反射得到实例对象:
string path=AppDomain.CurrentDomain.BaseDirectory;
Assembly ass = Assembly.LoadFrom(path + "IFrancis.dll");
Type ftype= ass.GetType("IFrancis.Francis");
object fobj=Activator.CreateInstance(ftype);
//剩余同理
第二部分:个人用用反射
使用反射技术,动态拼接sql语句
Insert示例1:
int beautyNum = 102;
string name = "name";
System.Text.StringBuilder sb = new StringBuilder()
Assembly ass = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IFrancis.dll");
Type type = ass.GetType("IFrancis.Francis");
string tableName = type.Name;
sb.AppendFormat(" Insert into {0} (", tableName);
PropertyInfo[] propertys = type.GetProperties();
foreach (PropertyInfo item in propertys)
{
sb.Append(item.Name + ",");
}
//去掉逗号
sb.Remove(sb.Length - 1, 1);
sb.Append(") values(" + beautyNum + ",‘" + name + "‘)");
Note:这样的写法,是根据IFrancis.dll程序集的属性为准来生成sql语句,一般的话,我个人会使用另外一种,根据Model实体对象来作为依据:
Insert示例2:
MFrancis model = new MFrancis() { BeautyNum = 103, Name = "name" };
string where = " where ....";
System.Text.StringBuilder updatesb = new StringBuilder();
Type type=Typeof(MFrancis);
string tableName=type.Name;
sb.AppendFormat(" insert into {0} (",tableName);
PropertyInfo[] PI= typeof(MFrancis).GetProperties();
List<SqlParameter> list2 = new List<SqlParameter>();
for (int i = 0; i < PI.Length; i++)
{
sb.Append(PI[i].Name+",");
}
sb.Remove(sb.Length-1,1);
sb.Append(") values(");
for (int i = 0; i < PI.Length; i++)
{
sb.Append("@"+PI[i].Name+",");
SqlParameter p = new SqlParameter("@"+PI[i].Name,PI[i].GetValue(model,null));
list2.Add(p);
}
sb.Remove(sb.Length-1,1);
update示例:
System.Text.StringBuilder updatesb = new StringBuilder();
PropertyInfo[] pi = typeof(MFrancis).GetProperties();//Model
List<SqlParameter> list = new List<SqlParameter>();
updatesb.AppendFormat("update {0} set ", tableName);
for (int i = 0; i < pi.Length; i++)
{
updatesb.AppendFormat(pi[i].Name + "[email protected]" + pi[i].Name + ",");
SqlParameter ps = new SqlParameter("@" + pi[i].Name, pi[i].GetValue(model, null));//类.属性名
list.Add(ps);
}
updatesb.Remove(updatesb.Length - 1, 1);
if (string.IsNullOrEmpty(where))
{
updatesb.Append(where);
}
这里的update和insert语句并不完整,因为实际还有where条件的存在,需要根据Primkey主键来拼接成一句完整的sql;另外的就是还有Model实体对象的合法性验证;