注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

I? =Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

C#精髓摘要(8)  

2011-07-24 14:16:35|  分类: C# & .NET |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

接前一部分,地址在这里

C#精髓》一书属于O'Reilly出版的动物系列技术书籍,这一系列的书算是赫赫有名了,趁现在有空,走马观花地读一下这本书。

C精髓摘要(2) - Castor - 趁年轻,多折腾~~
封面上的动物是星鼻鼹鼠(Condylura cristata)。与所有鼹鼠一样,星鼻鼹鼠主要居住在自己挖的地下隧道中,觅食时才出来。鼹鼠的身体上布满了防水的灰色短毛,大约6~8英寸长。它们的显著特征是长长的爪子,用于挖掘和觅食都非常理想。它们的眼睛、耳朵很小,牙齿非常锐利。视力和听觉很差。

星鼻鼹鼠的名字来源于它们鼻子上的25个触须,触须可以帮助鼹鼠找到食物,主要是昆虫、蠕虫、小鱼和其他小的池塘生物。星鼻鼹鼠是鼹鼠家族中的游泳健将,可以潜入水中捕鱼。它们喜欢住在沼泽中,分布于美国东北部和加拿大东南部。
星鼻鼹鼠是哺乳动物,雌鼹鼠每年可以生3~6只幼崽。
星鼻鼹鼠对人类的危害比其他鼹鼠要小,因为它偏爱水生食物,很少到人类的后院活动。
===================================================================================================

配件(Assembly

是一个逻辑包,包含清单(Manifest)、模块(Module)和可选的资源(Resource),包构成了部署和版本协调的基本单位,并为类型解析和安全权限控制创建了边界。

配件的元素

清单中包含一组运行时环境所需的描述配件信息的元数据。包括:

配件名、配件版本、共享名(可选),有符号的配件散列、文件列表、所引用配件列表、配件中类型的列表、所要求的最小和可选安全权限的集合、明确拒绝的安全权限的集合、文件、处理器和操作系统信息。产品名、所有人信息等细节。

部署

配件是.NET最小的部署单元。配件部署在应用程序目录的是私有配件,不能共享,也可由应用程序共享,称为共享配件,此时必须要有强名称(Strong Name),并部署在全局配件缓存(Global Assembly Cache)中。

Strong  Name包含一个名称,一个公共密钥和一个数字签证。

类型解析

类型的唯一标识符(TypeRef)由一个指向定义它的配件的引用和全限定类型名组成。CLR试图通过寻找各独立配件的正确版本验证类型的存在,来解析所有静态的TypeRef

反射

通过C#暴露的许多服务,如迟绑定、序列化、远程控制、属性信息等,都依赖于元数据。

通过其元数据来操作类型的方法成为反射,位于System.Reflection命名空间下的类型来实现,创建新的类型称为Reflection.Emit,位于System.Reflection.Emit下。

类型的层次

程序的基本单位是类型,包含成员和内嵌类型。程序还包括一个或者多个模块,和一个或者多个配件。运行时,这些元素都包含一个AppDomian,它不是由元数据描述的,但是在反射中很重要,它是运行时.NET程序的类型层次的根。

层次如下:

AppDomain

       配件

              模块

                     类型

                            成员

                                   内嵌类型

类型、成员、内嵌类型

反射处理的最基本元素是类型。类型包括构造函数、字段、属性、事件和方法。

配件和模块

配件是Win32 DLL的逻辑等价物,是类型部署、版本协调和重用的基本单位。模块是一个物理文件,如一个dll或者exe文件。

AppDomain

可以把它看作是Win32程序中进程的等价物。

提供了隔离性,为受管制代码提供了边界。

获取类型的实例

反射的核心是System.Type,是一个抽象的基类,提供对类型元数据的访问。可以使用GetType访问Type的实例。

直接获取类型

可以使用名称获取Type类,使用了GetType静态方法,如:

Type t = Type.GetType("System.Decimal");

还可以使用typeof运算符。如:

Type t = typeof(Decimal);

注意传递的参数类型。

方法的区别:GetType运行时计算,动态性好,而typeof是编译时计算,调用起来稍快。

在类型层次上反射(7.19

定位了Type的实例就可以通过类型访问代表成员、模块、配件、命名空间、AppDomain和内嵌类型的元数据。注意MemberInfo类的使用。

类型迟绑定

程序在运行时动态加载、实例化和使用类型。

以调用开销为代价。

激活

Activation,使用System.Activator类创建基于一个类型的新实例。ActivatorCreateInstance方法有多种版本。有可以绕过进程的,还有创建远程机器上的类型,或者在沙盒中(另外的AppDomain)创建类型,或者调用某个构造函数创建。

运行时创建新类型

使用System.Reflection.Emit中的方法创建。可在内存中定义动态配件,在配件中定义动态模块,在模块中定义新类型,在成员中生成程序逻辑实现的MSIL代码。

相关的类:AppDomainAssemblyNameILGeneratorAssemblyBuilderModuleBuilderTypeBuilderLocalBuilderMethodBuilder

MSDN中有一个非常精彩的例子:

using System;

using System.Reflection;

using System.Reflection.Emit;

using System.Threading;

class LocalBuilder_Sample

{

    public static void Main()

    {

        // Create an assembly.

        AssemblyName myAssemblyName = new AssemblyName();

        myAssemblyName.Name = "SampleAssembly";

        AssemblyBuilder myAssembly =Thread.GetDomain().DefineDynamicAssembly(myAssemblyName,AssemblyBuilderAccess.RunAndSave);

        // Create a module. For a single-file assembly

        //the module name is usually the same as the assembly name.

        ModuleBuilder myModule =myAssembly.DefineDynamicModule(myAssemblyName.Name,myAssemblyName.Name + ".dll", true);

        // Define a public class 'Example'.

        TypeBuilder myTypeBuilder = myModule.DefineType("Example", TypeAttributes.Public);

        // Create the 'Function1' public method, which takes an integer

        // and returns a string.

        MethodBuilder myMethod = myTypeBuilder.DefineMethod("Function1",MethodAttributes.Public | MethodAttributes.Static,typeof(String), new Type[] { typeof(int) });

        // Generate IL for 'Function1'. The function body demonstrates

        // assigning an argument to a local variable, assigning a

        // constant string to a local variable, and putting the contents

        // of local variables on the stack.

        ILGenerator myMethodIL = myMethod.GetILGenerator();

        // Create local variables named myString and myInt.

        LocalBuilder myLB1 = myMethodIL.DeclareLocal(typeof(string));

        myLB1.SetLocalSymInfo("myString");

        Console.WriteLine("local 'myString' type is: {0}", myLB1.LocalType);

        LocalBuilder myLB2 = myMethodIL.DeclareLocal(typeof(int));

        myLB2.SetLocalSymInfo("myInt", 1, 2);

        Console.WriteLine("local 'myInt' type is: {0}", myLB2.LocalType);

        // Store the function argument in myInt.

        myMethodIL.Emit(OpCodes.Ldarg_0);

        myMethodIL.Emit(OpCodes.Stloc_1);

        // Store a literal value in myString, and return the value.

        myMethodIL.Emit(OpCodes.Ldstr, "string value");

        myMethodIL.Emit(OpCodes.Stloc_0);

        myMethodIL.Emit(OpCodes.Ldloc_0);

        myMethodIL.Emit(OpCodes.Ret);

        // Create "Example" class.

        Type myType1 = myTypeBuilder.CreateType();

        Console.WriteLine("'Example' is created.");

        myAssembly.Save(myAssemblyName.Name + ".dll");

        Console.WriteLine("'{0}' is created.", myAssemblyName.Name + ".dll");

        // Invoke 'Function1' method of 'Example', passing the value 42.

        Object myObject2 = myType1.InvokeMember("Function1",BindingFlags.InvokeMethod, null, null, new Object[] { 42 });

        Console.WriteLine("Example.Function1 returned: {0}", myObject2);

    }

}

/* This code example produces the following output:

local 'myString' type is: System.String

local 'myInt' type is: System.Int32

'Example' is created.

'SampleAssembly.dll' is created.

Example.Function1 returned: string value

 */

  评论这张
 
阅读(1034)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016