C#反射

编译过程

1、C# 代码编译为DLL  EXE。

  其中.exe文件是一个自己执行的程序集,而.dll将被其他程序集加载后运行。

2、DLL  EXE 中的语言是 IL中间语言(当然里面还有一部分是元数据),还有其他一部分信息。

3、JIT及时编译,把IL在编译为机器语言,然后CLR把机器语言缓存起来。

DLL可以跨平台,但是不同操作系统的JIT可能不一样。(和JAVA中的Jre一个概念)

基础知识:.NET

  如果有哪一个公司面试问什么是.NET,我觉得可以不用考虑这一家公司了。

  概念:微软的一个面向互联网软件服务的一个战略。把计算机广泛的应用,方便用户使用,提高企业效率,丰富服务提供商的服务内容,值得注意的是有三个角色,用户  企业 服务商。(最大的感受大公司内部电脑  域管理,OA系统和域打通,工作流)

  目标:Code Once,Run Anywhere。  发个牢骚     目标很远大,现实很悲凉。

  可以认为.NET是一个商标,在他下面有很多产品和服务。

基础知识:.NET Framework

 是用于Windows的托管代码编程模型

http://blog.csdn.net/shanyongxu/article/details/50907629

http://blog.sina.com.cn/s/blog_5c45656c0100wqkd.html

http://www.cnblogs.com/xifengyeluo/p/5894747.html

每种语言都提供了CLR/CTS的一个子集以及CLS的一个超集(但不一定是同一个超集)

托管代码,非托管代码:运行在.NET Framework上的代码就是托管代码(C#   VB.NET生成的IL都是运行在Fra上的),非托管代码例如C++    C等代码,直接生成机器码的。

CTS:公共类型,.NET Fraemork中定义了一套托管类型,任何.NET框架的语言种类型必须遵守这套规则。任何满足了这套规则的高级语言都可以称为面向.NET框架的语言.C#和VB.net不过是微软自己开发的一套符合了CTS的语言.实际上还有很多的组织或团队也开发出了这样的语言,比如Delphi.Net,FORTRAN等.

  CTS规范规定,一个类型可以包含零个或者多个成员。

  CTS还指定了类型可视性规则以及类型成员的访问规则。比如private,public,family(C#中为protected),Assembly(C#中为internal),,family and assembly(C#中没有对应的实现),family or assembly(C#中为protected internal).

     CTS还为类型继承、虚方法、对象生成期等定义了相应的规则。

  所有类型最终必须从预定义的System.Object类型继承。

  (从过个父类继承编译器会报错,CTS也会检测这个错误)

CLS:公共语言规范,想要在.NET Framework上运行的程序必须遵守这个规范,包含函数调用方式,参数传递方式,数据类型和异常处理方式.。就是一个语法规范。CLS的规则,在CLR中,一个类型的每个成员要么是一个字段(数据),要么是一个方法(行为)。CLS是CTS的一个子集。FCL类库都符合CLS规范,所以无论是C#   VB.NET 都能使用FCL类库。.NET为我们提供了一个特性CLSCompliant,便于在编译时检查程序集是否符合CLS。

CLR:通用语言开发环境,或者公共语言运行时。CLR是一个软件层或代理,它管理了.NET程序集的执行,主要包括:管理应用程序集,加载和运行程序集,安全检查,将CIL代码即时编译为机器代码,异常处理,对象析构和垃圾回收.相对于编译时(Compile time),这些过程发生在程序运行的过程中,因此,将这个软件层命名为了运行时,实际上它本身与事件时没有什么太大关系。

  由于CLR本身用于管理托管代码,因此它是由非托管代码编写的,并不是一个包含了托管代码的程序集,也不能使用IL DASM进行查看.

FCL:Framework Class Library,我们每天用的都是FCL,各种类库。

  从功能上看,可以将FCL框架类库划分为以下几层:

  最内一层,由BCL的大部分组成,主要作用是对.NET框架,.NET运行时以及CIL语言本身进行支持,例如基元类型,集合类型,线程处理,应用程序域,运行时,安全性,互操作等.

  中间一层,包含了对操作系统功能的封装,例如文件系统,网络连接,图形图像,XML操作等.

  最外一层,包含各种类型的应用程序,例如Window Forms,Asp.NET,WPF,WCF,WF等.

BCL:Base Class Library,例如mscorlib.dll,已经和CLR融为一体,及时项目中删除这个DLL的引用,代码中还是可以使用他。BCL是FCL的一个子集,BCL中包含了与编译器以及CIL语言关系紧密的核心类型,以及常见开发任务中都会用到的类型。

反射-Assembly-程序集

命名空间:using System.Reflection;

定义:表示一个程序集,它是一个可重用、无版本冲突并且可自我描述的公共语言运行时应用程序构造块。

  个人理解就是一个加载出来的DLL。反射读取的是程序集的元数据。

//默认当前路径下的DLL文件,不需要后缀
            Assembly user = Assembly.Load(@"User");
            //DLL的路径+名称
            var user1 = Assembly.LoadFile(@"E:\Progect\C#\MyReflectioin\MyReflectioin\bin\Debug\User.dll");
            var user2= Assembly.LoadFrom("User.dll");
            //获取模块,C#在VS中一个程序集就是一个DLL,  一个DLL中可以包括多个程序集,就会有多个模块。
            var modus= user.GetModules();
            var types= user.GetTypes();
            //获取类型  就是命名空间+类名称
            var userType = user.GetType("User.User");
             foreach (var item in modus)
            {
                Console.WriteLine(item.Name);
            }
            foreach (var item in types)
            {
                Console.WriteLine(item.Name);
            }
View Code

 

反射-Type-类

 获取类型,一般为Class的类型

Assembly user = Assembly.Load(@"User");
var types = user.GetTypes();
//获取类型  就是命名空间+类名称
var userType = user.GetType("User.User");

var userType1 = typeof(User.User);
User.User u = new User.User();

//创建实例,实例必须指定是哪一个类型,就是哪一个class
var userInstance= user.CreateInstance("User.User");
var userInstance1 = Activator.CreateInstance(userType1);
View Code

Activator:包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。此类不能被继承。public sealed class Activator : _Activator  

    说白了就是创建对象的。

反射-模块

 .NET的程序集是可以由多个文件及程序集清单由程序集链接器合并成一个程序集的,反射的Modules就是这些文件,叫做“模块”...C#和VB用VS编译生成的程序集只支持一个模块,只有C++.NET或命令行编译才支持多文件程序集

1 //获取模块,C#在VS中一个程序集就是一个DLL,  一 个DLL中可以包括多个程序集,就会有多个模块。
2 var modus = user.GetModules();
反射-属性

 

//s所有公共属性
var allUserPro= userType1.GetProperties();
foreach (var item in allUserPro)
{
    if (item.PropertyType == typeof(int))
    {
        item.SetValue(userInstance1, 2);
    }
    else if (item.PropertyType == typeof(string))
    {
        item.SetValue(userInstance1, "lalala");
    }
    Console.WriteLine(item.Name+":"+item.GetValue(userInstance1).ToString());
}
//BindingFlags类型搜索
var allUserProFlag = userType1.GetProperties(BindingFlags.Static);

 

反射-字段

 

var userFiledsFlags = userType1.GetFields(BindingFlags.Static | BindingFlags.Public);
var userFields = userType1.GetFields();
foreach (var item in userFields)
    {
         item.SetValue(userInstance1, "123123123");
         Console.WriteLine(item.Name + ":" + item.GetValue(userInstance1));
    }

 

反射-特性

 

#region 类特性
var userAttribute = userType.GetCustomAttribute(typeof(BaseAttCAttribute));
var userAttributes = userType.GetCustomAttributes();
foreach (var item in userAttributes)
{
    Console.WriteLine(item.ToString());
}
#endregion
#region 属性特性
var userProLinq = userType.GetProperties().Where(t=>t.GetCustomAttributes().Where(f=>f.GetType()==typeof(PropAttribute)).Count()>0);
foreach (var item in userProLinq)
{
    Console.WriteLine(item.Name);
    foreach (var itemAtr in item.GetCustomAttributes())
    {
        Console.WriteLine(" " + itemAtr.ToString());
    }
}


var userPro = userType.GetProperties();
foreach (var item in userPro)
{
    Console.WriteLine(item.Name);
    foreach (var itemAtr in item.GetCustomAttributes())
    {
        Console.WriteLine(" "+itemAtr.ToString());
    }
}
#endregion
View Code

 

反射-方法

 

#region 反射-所有方法
var allMethods = userType.GetMethods();
foreach (var item in allMethods)
{
    Console.WriteLine(item.Name);
}
#endregion

#region 反射-不带参数方法
var noPMethod = userType.GetMethod("GetMyID");
Console.WriteLine(noPMethod.Invoke(userInstance, null).ToString());
#endregion

#region 反射-带参数方法
var withPMethod = userType.GetMethod("GetMyName");
Console.WriteLine(withPMethod.Invoke(userInstance, new object[] { "你好啊" }).ToString());
#endregion

#region 反射-构造函数
var allConstrus = userType.GetConstructors();
foreach (var item in allConstrus)
{
    string paraTypes = "";
    foreach (var itemP in item.GetParameters())
    {
        paraTypes += (itemP.ParameterType + ":" + itemP.Name + "      ");
    }
    Console.WriteLine(item.Name + "      参数:" + paraTypes);
}

//通过构造函数创建实例
var pConstrus = userType.GetConstructor(new Type[] { typeof(string) });
var userInstanceP = pConstrus.Invoke(new object[] { "张三" });

var withPMethodP = userType.GetMethod("GetMyName");
Console.WriteLine(withPMethodP.Invoke(userInstanceP, new object[] { "你好啊" }).ToString());


#endregion

 

反射-私有类型

 

#region 反射-私有属性方法等   BindingFlags解释
//私有字段
var priPro = userType.GetFields(BindingFlags.NonPublic|BindingFlags.Instance);
foreach (var item in priPro)
{
    Console.WriteLine(item.Name);
}
#endregion

MSDN:https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=ZH-CN&k=k(System.Reflection.BindingFlags);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5.2);k(DevLang-csharp)&rd=true

http://blog.csdn.net/qq_32452623/article/details/53401890

 

源码下载

posted @ 2017-08-14 15:02  西伯利亚的狼  阅读(328)  评论(0编辑  收藏  举报