知识大全 C#4.0动态关键字与COM

Posted

篇首语:遇到一些人,知道一些事,才能懂的理解与珍惜,才能看清自己的方向。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 C#4.0动态关键字与COM相关的知识,希望对你有一定的参考价值。

C#4.0动态关键字与COM  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  在我成为 C/ 开发人员之后 尤其是在 Microsoft 推出之前 我经常指责采用 Visual Basic 进行编程的同事选择使用那样一种弱类型化的语言         有那么一段时间 进行静态类型化和强类型化编程是获得良好的体验的明显选择 但是事物总是要发展变化的 当今的 开发人员社区(看起来几乎所有前 C/C++ 开发人员都已经转移到这里)经常发现他们明确需要一个更加动态的编程模型 上个月 我介绍了 Microsoft 在 C# 和 Visual Studio 中提供的一些动态编程功能 这个月 我将深入探讨一些相关方案 首先要介绍 C# 最吸引人的原因之一 可以在 NET Framework 中轻松实现 对象编程         轻松访问 对象        如果一个对象的结构和行为不是由完全静态定义的类型(编译器全面了解该类型)描述的话 该对象就是动态的 不可否认 动态 一词在这种情况下听起来太宽泛了 因此让我们看一个简单的示例 在 Script 等脚本语言中 以下代码能够成功运行         Set word = CreateObject( Word Application )        CreateObject 函数假设它获得的 string 参数是某个已注册 对象的 progID 它创建该组件的一个实例 并返回该实例的 IDispatch 自动化接口 IDispatch 接口的细节在脚本语言的任何层级都绝对看不到 重要的是您可以编写如下代码         Set word = CreateObject( Word Application )        word Visible = True        Set doc = word Documents Add()        Set selection = word Selection        selection TypeText Hello world         selection TypeParagraph()        doc SaveAs(fileName)       

        在这段代码中 您首先创建对组件的引用 以便自动执行底层 Microsoft Word 应用程序的行为 接着 您显示 Word 主窗口 添加一个新文档 在其中输入一些文字 然后将文档保存到某个位置 这段代码清晰易懂 而且更重要的是 能够正常运行         但它能正常运行要归功于 Script 提供的特殊功能 后期绑定 后期绑定意味着直到执行流程遇到给定对象之前 该对象的类型都是未知的 当执行流程需要执行给定对象时 运行时环境才会开始确保要调用的该对象成员确实存在 然后再进行调用 在代码真正执行之前 不会对其进行任何提前检查         您可能知道 像 这样的脚本语言并没有编译器 但是 Visual Basic(包括 CLR 版本)多年来一直有一项类似的功能 我承认 我经常会羨慕我的 Visual Basic 同事能够更轻松地使用 对象 而需要进行互操作的应用程序(例如 Office)经常采用这种有价值的构造块 事实上 在有些情况下 即使整个应用程序是用 编写的 我的团队也会用 Visual Basic 编写一部分互操作代码 这有点令人意外?多语言编程不是一种新的前沿技术吗?        在 Visual Basic 中 CreateObject 函数的存在是为了解决顽固的兼容性问题 重点在于基于 的语言在设计时考虑的是前期绑定NET Framework 能够处理 互操作性方案 但是这种方案从来不能由编程语言通过关键字和工具来提供支持 这种情况直到 C# 才有所改观         C# (和 Visual Basic)拥有动态查询功能 这表明后期绑定现在对于 NET Framework 开发人员来说已经切实可行了 借助动态查询功能 您可以绕过静态类型检查 在代码中直接访问方法 属性 索引生成器属性和字段 而留待运行时进行解析                 还通过识别成员声明中的默认值来实现可选参数 这意味着 在调用拥有可选参数的成员时 可以省略可选参数 而且 既可以按名称也可以按位置来传递参数 最后 C# 中改进的 绑定功能意味着以前是静态且强类型化的语言现在也支持脚本语言的一些常见功能 在您了解如何利用新的动态关键字 实现与 对象的流畅操作之前 让我们稍稍深入了解一下动态类型查询的内部机制         动态语言运行时        当您在 Visual Studio 中将某个变量声明为动态时 其默认配置中根本不会有 IntelliSense 有趣的是 如果您安装一个类似 ReSharper (/resharper) 的附加工具 就可以通过 IntelliSense 获得一些有关动态对象的不完全信息 图 显示了带有和不带 ReSharper 的代码编辑器 该工具仅仅列出该动态类型上看起来已经定义的成员 在最低限度下 动态对象是 System Object 的实例    

  

  图 在带有和不带 ReSharper 的情况下 Visual Studio 中的动态对象的 IntelliSense        让我们看看当编译器遇到以下代码时会发生什么情况(这段代码设计得极其简单 目的是简化对实现细节的理解)         class Program                static void Main(string[] args)                dynamic x = ;        Console WriteLine(x)                         在第二行中 编译器不会尝试解析符号 WriteLine 也不会像传统的静态类型检查器一样发出警报或错误 只要遇到 dynamic 关键字 C# 的表现就会变得像是解释性语言 结果 编译器会生成一些临时代码 用来解释涉及动态变量或参数的表达式 解释器基于动态语言运行时 (DLR) 是 机制中的一个全新组件 若要使用更具体的术语 编译器必须使用 DLR 所支持的抽象语法来生成表达式树 并将其传递给 DLR 库进行处理 在 DLR 中 由编译器提供的表达式被封装在动态更新的站点对象中 站点对象负责实时将方法绑定到对象 图 显示了真实代码的充分简化版本 该真实代码是由前述的简单程序生成的        

        图 中的代码已经过编辑和简化以方便阅读 但它显示了实际情况的要点 动态变量映射到 System Object 实例 然后就会在 DLR 中为程序创建一个站点 该站点负责管理 WriteLine 方法及其参数与目标对象之间的绑定 该绑定维持在类型 Program 的上下文中 为了对动态变量调用方法 Console WriteLine 您将调用该站点 并传递目标对象(本例中为 Console 类型)及其参数(本例中为动态变量) 该站点将在内部检查目标对象是否真的拥有成员 WriteLine 并且该成员能够接受类似于变量 x 中目前存储的对象这样的参数 如果有任何问题 运行时就会引发 RuntimeBinderException         图 动态变量的真正实现        internal class Program                private static void Main(string[] args)                object x = ;        if (MainSiteContainer site == null)                MainSiteContainer site = CallSite<        Action<CallSite Type object》        Create(Binder InvokeMember(        WriteLine         null         typeof(Program)         new CSharpArgumentInfo[]         CSharpArgumentInfo Create(…)        ))                 MainSiteContainer site Target Invoke(        site typeof(Console) x)                 private static class MainSiteContainer                public static CallSite<Action<CallSite Type object》 site ;                                使用 对象        现在 新的 能够在基于 的应用程序中简单轻松地使用 对象 让我们看看如何在 C# 中创建一个 Word 文档 并且对您在 NET 和 NET 中需要的代码进行比较 示例应用程序将基于给定的模板创建一个新的 Word 文档 填入一些内容 并将其保存到一个指定位置 模板包含一些书签 用于容纳一些常用信息 无论您面向的是 NET Framework 还是 NET Framework 通过编程来创建 Word 文档的第一步都是添加 Microsoft Word 对象库(请参见图 )         图 引用 Word 对象库        在 Visual Studio 和 NET Framework 之前 若要完成此操作 您需要类似图 所示的代码         图 在 C# 中创建新的 Word 文档        public static class WordDocument                public const String TemplateName = @ Sample dotx ;        public const String CurrentDateBookmark = CurrentDate ;        public const String SignatureBookmark = Signature ;        public static void Create(String file DateTime now String author)                // Must be an Object because it is passed as a ref        Object missingValue = Missing Value;        // Run Word and make it visible for demo purposes        var wordApp = new Application Visible = true ;        // Create a new document        Object template = TemplateName;        var doc = wordApp Documents Add(ref template         ref missingValue ref missingValue ref missingValue)         doc Activate()         // Fill up placeholders in the document        Object bookmark_CurrentDate = CurrentDateBookmark;        Object bookmark_Signature = SignatureBookmark;        doc Bookmarks get_Item(ref bookmark_CurrentDate) Range Select()         wordApp Selection TypeText(current ToString())         doc Bookmarks get_Item(ref bookmark_Signature) Range Select()         wordApp Selection TypeText(author)         // Save the document        Object documentName = file;        doc SaveAs(ref documentName         ref missingValue ref missingValue ref missingValue         ref missingValue ref missingValue ref missingValue         ref missingValue ref missingValue ref missingValue         ref missingValue ref missingValue ref missingValue         ref missingValue ref missingValue ref missingValue)         doc Close(ref missingValue         ref missingValue ref missingValue)         wordApp Quit(ref missingValue         ref missingValue ref missingValue)                                 为了与 自动化接口交互 您经常需要 Variant 类型 当您在基于 的应用程序中与 自动化对象交互时 您需要将 Variants 表示成普通对象 其直接后果是您不能使用字符串来指示 Word 文档所用的模板文件的名称 因为必须通过引用来传递 Variant 参数 您不得不求助于 Object 如下所示         Object template = TemplateName;        var doc = wordApp Documents Add(ref template         ref missingValue ref missingValue ref missingValue)         要考虑的第二个方面是 Visual Basic 和脚本语言远不如 严格 例如 这些语言不会强制要求您指定 对象声明上某个方法的所有参数 Documents 集合的 Add 方法需要四个参数 而除非您的语言支持可选参数 否则就不能忽略这些参数         正如前文所述 C# 支持可选参数 这意味着 尽管直接用 C# 来重新编译图 中的代码就能正常使用 您可能仍会重写这段代码 删除所有用来传递缺少的值的 ref 参数 如下所示         Object template = TemplateName;        var doc = wordApp Documents Add(template)         借助 C# 中新的 省略 ref 支持 图 中的代码变得更加简单 而且更重要的是 它变得更容易阅读 且语法上与脚本代码更像 图 包含编辑过的版本 该版本能够用 C# 进行正确编译 并且与图 中的代码效果相同         图 在 C# 中创建新的 Word 文档        public static class WordDocument                public const String TemplateName = @ Sample dotx ;        public const String CurrentDateBookmark = CurrentDate ;        public const String SignatureBookmark = Signature ;        public static void Create(string file DateTime now String author)                // Run Word and make it visible for demo purposes        dynamic wordApp = new Application Visible = true ;        // Create a new document        var doc = wordApp Documents Add(TemplateName)         templatedDocument Activate()         // Fill the bookmarks in the document        doc Bookmarks[CurrentDateBookmark] Range Select()         wordApp Selection TypeText(current ToString())         doc Bookmarks[SignatureBookmark] Range Select()         wordApp Selection TypeText(author)         // Save the document        doc SaveAs(fileName)         // Clean up        templatedDocument Close()         wordApp Quit()                                 图 中的代码允许您使用普通 类型来调用 对象 而且 可选参数使得它更加简单         中引入的动态关键字和其他 互操作功能不会使代码的运行速度明显加快 但能让您像编写脚本一样编写 C# 代码 对于 对象来说 这种成果可能与性能的提升一样重要         无 PIA 部署        从 NET Framework 推出以来 您就可以将 对象包装到托管类中 然后从基于 NET 的应用程序中使用 为了实现此目的 您需要使用由 对象的供应商提供的主互操作程序集 (PIA) PIA 必不可少 必须与客户端应用程序一起部署 但是 很多时候 PIA 都太大了 并且会包含整个 API 因此将它们打包到安装程序中不是什么令人愉快的经验         Visual Studio 提供了无 PIA 选项 无 PIA 是指编译器能够嵌入您在当前程序集中从 PIA 获取的必要定义 因此 只有真正需要的定义才会进入最终的程序集 而不需要将供应商的 PIA 整个打包到安装程序中 图 显示了 属性 框中的选项 该选项在 Visual Studio 中实现了无 PIA         cha138/Article/program/net/201311/11486

相关参考

知识大全 .NET 4.0函数式编程与协调数据结构

.NET4.0函数式编程与协调数据结构  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  协调数据结

知识大全 详解C# 4.0中的新对象ExpandoObject

详解C#4.0中的新对象ExpandoObject  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 C# 4.0中泛型协变性和逆变性详解

C#4.0中泛型协变性和逆变性详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  VS的推出会为

知识大全 .NET框架4.0中都有些什么

.NET框架4.0中都有些什么?  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  前不久在美国洛杉

知识大全 Enterprise Library 4.0下载

EnterpriseLibrary4.0下载  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  En

知识大全 JBoss Drools 4.0 发布

JBossDrools4.0发布  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nbs

知识大全 详解.NET 4.0代码契约组件

详解.NET4.0代码契约组件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  代码契约组件是对N

知识大全 安卓4.0系统,如何使软件安装的默认位置为SD卡

安卓4.0系统,如何使软件安装的默认位置为SD卡!  以下文字资料是由(历史新知网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!安卓4.0

知识大全 .NET框架4.0新功能先睹为快

.NET框架4.0新功能先睹为快  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  前不久在美国洛杉

知识大全 .Net PetShop 4.0的层次结构

.NetPetShop4.0的层次结构  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  说起软件系