前言:使用反射也有几年了,但是一直觉得,反这个概念很抽象,今天有时间就来总结下这个知识点。

1、为什么需要反射:

最初使用反射的时候,作为小菜总是不理解,既然可以通过new 一个对象的方式得到对象,然后通过对象去调用属性和方法,那么为什么还需要反射去调用呢?后来使用多了发现这就是一个先绑定还是后绑定的问题,很多初使用反射的开发人员通常都会有类似这种疑虑:既然在开发时就能够写好代码,干嘛还放到运行期去做,不光繁琐,而且效率也受影响。博主觉得主要是适用性的问题,如果你的系统没有那么高的扩展性和灵活性要求,你大可不必考虑反射。但在架构设计时,很多东西都需要考虑复用性,并且在某些特定的场景下你得不到具体的类时,你就必须用到反射。博主总结了下自己使用过的反射场景:

(1)有时不知道具体的类型,可以通过dll去得到类的对象;

(2)某些特殊方法,传过来的是泛型类,需要通过反射处理某些特殊的业务;

(3)通用方法DataTable和List<T>的相互转化时需要用到反射;

2、如何使用反射:

(1)反射dll得到类成员:

在一个未知的dll里面有一个Person类

public class Person
{
private string address;
private string email;
public string Name { set; get; }
public int Age { set; get; }
public void SayHello()
{
Console.WriteLine("你好");
}
public static string MystaticPro { set; get; }
public static void MyStatic()
{
Console.WriteLine("我是static方法");
}
}

通过反射dll得到Person类

static void Main(string[] args)
{
   //通过类名称得到类型
   //var assembly = Assembly.Load("Ewin.Client.Web");//参数为程序集的名称
   //var oType = assembly.GetType("Ewin.Client.Web.Controllers." + strType); //反射dll
var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll");
var oAssembly = Assembly.LoadFile(strDllPath);
var lstTypes = oAssembly.GetTypes();
foreach (var oType in lstTypes)
{
if (oType.Name == "Person")
{
//默认得到类下面的所有public成员
var lstMembers = oType.GetMembers();
foreach (var oMem in lstMembers)
{
Console.WriteLine("GetMembers()方法得到的成员名称:"+oMem.Name);
}
Console.WriteLine("");
//默认得到类下面的所有public属性
var lstProperty = oType.GetProperties();
foreach (var oProp in lstProperty)
{
Console.WriteLine("GetProperties()方法得到的成员名称:" + oProp.Name);
}
Console.WriteLine("");
//默认得到类下面的所有public字段
var lstField = oType.GetFields();
foreach (var oField in lstField)
{
Console.WriteLine("GetFields()方法得到的成员名称:" + oField.Name);
}
}
}
Console.ReadKey();
}

得到结果

(2)反射对象的私有成员:

一般私有属性的用法比较少,我们就以私有字段为例来说明,还是上面的例子:

static void Main(string[] args)
{
//反射dll
var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll");
var oAssembly = Assembly.LoadFile(strDllPath);
var lstTypes = oAssembly.GetTypes();
foreach (var oType in lstTypes)
{
if (oType.Name == "Person")
{
//默认得到类下面的所有public字段
var lstField = oType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var oField in lstField)
{
Console.WriteLine("GetFields()方法得到的成员名称:" + oField.Name);
}
}
}
Console.ReadKey();
}

(3)反射对象的静态成员:

static void Main(string[] args)
{
//反射dll
var strDllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll\\ReflectorDLL.dll");
var oAssembly = Assembly.LoadFile(strDllPath);
var lstTypes = oAssembly.GetTypes();
foreach (var oType in lstTypes)
{
if (oType.Name == "Person")
{
//默认得到类下面的所有public成员
var lstMembers = oType.GetMembers(BindingFlags.Public|BindingFlags.Static);
foreach (var oMem in lstMembers)
{
Console.WriteLine("GetMembers()方法得到的成员名称:" + oMem.Name);
}
Console.WriteLine(""); //默认得到类下面的所有public字段
var lstField = oType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var oField in lstField)
{
Console.WriteLine("GetFields()方法得到的成员名称:" + oField.Name);
}
}
}
Console.ReadKey();
}

还有枚举类型等等就不一一介绍了,基本上都是在BindingFlags这个上面做处理。

(4)反射得到对象以及对象的操作:

反射得到对象的方法主要有两种

public static T GetModel<T>(T oModel)
{
var model = default(T) ;
//得到对象的方法一:
model = (T)typeof(T).GetConstructor(new System.Type[] { }).Invoke(new object[] { });
//反射得到泛型类的实体 //得到对象的方法二:
model = (T)Activator.CreateInstance(typeof(T));
//逻辑处理......
return model;
}

对象属性的取值和赋值:

//List集合转换为DataTable
public static DataTable ListFillTable(object obj)
{
if (!(obj is IList))
{
return null;
}
var objlist = obj as IList;
if (objlist == null || objlist.Count <= 0)
{
return null;
}
var tType = objlist[0];
DataTable dt = new DataTable(tType.GetType().Name);
DataColumn column;
DataRow row;
System.Reflection.PropertyInfo[] myPropertyInfo = tType.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var t in objlist)
{
if (t == null)
{
continue;
}
row = dt.NewRow();
for (int i = 0, j = myPropertyInfo.Length; i < j; i++)
{
System.Reflection.PropertyInfo pi = myPropertyInfo[i];
string name = pi.Name;
if (dt.Columns[name] == null)
{
var coltype = pi.PropertyType;
if (coltype.Name == "Nullable`1")
{
//coltype = typeof(System.DBNull);
column = new DataColumn(name);
}
else
{
column = new DataColumn(name, coltype);
}
dt.Columns.Add(column);
}
row[name] = pi.GetValue(t, null);
}
dt.Rows.Add(row);
}
return dt;
}

C#基础系列:反射笔记的更多相关文章

  1. C#基础系列——反射笔记

    前言:使用反射也有几年了,但是一直觉得,反这个概念很抽象,今天有时间就来总结下这个知识点. 1.为什么需要反射: 最初使用反射的时候,作为小菜总是不理解,既然可以通过new 一个对象的方式得到对象,然 ...

  2. C#基础系列-反射

    1.反射的定义 反射(Reflection),是.Net中获取运行时类型信息的方式.程序集中有关程序及其类型的数据被称为元数据(metadata).程序在运行时,可以查看其它程序集或其本身的元数据.一 ...

  3. C#基础系列 - 反射基础

    反射用于在程序运行过程中,获取类里面的信息或发现程序集并运行的一个过程.通过反射可以获得.dll和.exe后缀的程序集里面的信息.使用反射可以看到一个程序集内部的类,接口,字段,属性,方法,特性等信息 ...

  4. C#基础系列——Attribute特性使用

    前言:上篇 C#基础系列——反射笔记 总结了下反射得基础用法,这章我们来看看C#的另一个基础技术——特性. 1.什么是特性:就博主的理解,特性就是在类的类名称.属性.方法等上面加一个标记,使这些类.属 ...

  5. C#基础系列——小话泛型

    前言:前面两章介绍了C#的两个常用技术:C#基础系列——反射笔记 和 C#基础系列——Attribute特性使用 .这一章来总结下C#泛型技术的使用.据博主的使用经历,觉得泛型也是为了重用而生的,并且 ...

  6. C#基础系列——委托和设计模式(二)

    前言:前篇 C#基础系列——委托实现简单设计模式 简单介绍了下委托的定义及简单用法.这篇打算从设计模式的角度去解析下委托的使用.我们知道使用委托可以实现对象行为(方法)的动态绑定,从而提高设计的灵活性 ...

  7. C#基础系列——再也不用担心面试官问我“事件”了

    前言:作为.Net攻城狮,你面试过程中是否遇到过这样的问题呢:什么是事件?事件和委托的区别?既然事件作为一种特殊的委托,那么它的优势如何体现?诸如此类...你是否也曾经被问到过?你又是否都答出来了呢? ...

  8. C#基础系列——异步编程初探:async和await

    前言:前面有篇从应用层面上面介绍了下多线程的几种用法,有博友就说到了async, await等新语法.确实,没有异步的多线程是单调的.乏味的,async和await是出现在C#5.0之后,它的出现给了 ...

  9. C#基础系列——一场风花雪月的邂逅:接口和抽象类

    前言:最近一个认识的朋友准备转行做编程,看他自己边看视频边学习,挺有干劲的.那天他问我接口和抽象类这两个东西,他说,既然它们如此相像, 我用抽象类就能解决的问题,又整个接口出来干嘛,这不是误导初学者吗 ...

  10. c#基础系列(转)

    转:http://www.cnblogs.com/landeanfen/p/4953025.html C#基础系列——一场风花雪月的邂逅:接口和抽象类 前言:最近一个认识的朋友准备转行做编程,看他自己 ...

随机推荐

  1. 几个类和Table的方法

    public class TableHelper { public static DataTable CreateTableFromClass(Type t) { DataTable dt = new ...

  2. 【BZOJ1001】狼抓兔子(平面图最小割转最短路)

    题意:有一张平面图,求它的最小割.N,M.表示网格的大小,N,M均小于等于1000. 左上角点为(1,1),右下角点为(N,M).有以下三种类型的道路  1:(x,y)<==>(x+1,y ...

  3. 【NOIP2016练习】T1 string (计数)

    题意: 思路: ; ..]of int64; n,k,i:longint; ans,x,y:int64; s,t:ansistring; function c(x,y:longint):int64; ...

  4. c#.net分类上升达人~~~呵呵。。。

    原文发布时间为:2008-11-11 -- 来源于本人的百度文章 [由搬家工具导入] 觉得自己蛮无聊的~~~~~~~~~(>_<)~~~~

  5. 关于TS返回 Can't use function return value in write context 问题

    在项目开发过程中,出现某一接口文件间歇性出现500错误,间歇性出现说明是有条件才会产生,查看错误日志显示:Fatal error: Can't use function return value in ...

  6. 域名缓存侦测(DNS Cache Snooping)技术

    域名缓存侦测(DNS Cache Snooping)技术 在企业网络中,通常都会配置DNS服务器,为网络内的主机提供域名解析服务.这些DNS不仅解析自己的私有域名,还会用递归方式,请求公网的DNS解析 ...

  7. codevs贪吃的九头龙

    传说中的九头龙是一种特别贪吃的动物.虽然名字叫“九头龙”,但这只是说它出生的时候有九个头,而在成长的过程中,它有时会长出很多的新头,头的总数会远大于九,当然也会有旧头因衰老而自己脱落.有一天,有M 个 ...

  8. 快速比较两个uiimage是否相等防止使用原始dsdata造成界面卡顿问题

    UIImage *imageLater = image1; UIImage *imagePre = image2; if (imageLater == imagePre){....}

  9. MVP的理解和使用

    MVP大家应该差不多都知道了,他其实是MVC的升华版,差不多是在view和model中加了一个调节器,这样view不能直接调用model中得数据,而是通过presenter来进行操作,此外Presen ...

  10. WEBLOGIC启动后,重启后控制台进入缓慢、延迟,探查WEBLOGIC

    本文说的是解决过程,可直接点击本行略过探查内容,跳到最后的解决办法!! 现象: 1.WEBLOGIC安装在 CENTOSopenSUSE 等LINUX或者UNIX机器上,无论是虚拟机或者PC或者服务器 ...