[转载]细说CodeDom(10):生成异常处理语句

作者:老周,原文地址

写完这一篇,大概可以准备过年了,就算是这系列文章的收尾吧。

异常处理语句,就是常说的try…catch语句,有时候,也会带有finally子句。要生成异常处理语句,得用到CodeTryCatchFinallyStatement类,它包含三个部分。

  1. TryStatements:尝试执行的代码块。
  2. CatchClauses:捕捉异常的代码块。CatchClauses是一个子句集合,因为一个try语句可以包含N个catch子句,而每个catch块都由CodeCatchClause类来表示,使用时应提供要捕捉的异常的类型,异常对象的临时变量名,以及catch块的语句集合。
  3. FinallyStatements:finally语句块,不管会不会发生异常,finally中的语句会执行。

下面看一个最常见的try语句的生成。

阅读更多

[转载]细说CodeDom(9):动态编译

作者:老周,原文地址

知道了如果构建代码文档,知道了如何生成代码,那么编译程序集就很简单了。

CodeDomProvider 类提供了三个可以执行编译的方法:

  1. CompileAssemblyFromSource——这个好懂,也好办,就是用字符串直接构建代码,然后传给这个方法,就可以把源代码编译了。
  2. CompileAssemblyFromFile——这个是把一个代码文件传给方法进行编译,文件中包含源代码。
  3. CompileAssemblyFromDom——这个重载版本跟我们之前所学的内容关联性最大,因为它是把 CodeCompileUnit 实例传进去来编译的。
阅读更多

[转载]细说CodeDom(8):分支与循环

作者:老周,原文地址

有人会问,为啥 CodeDom 不会生成 switch 语句,为啥没生成 while 语句之类。要注意,CodeDom只关心代码逻辑,而不是语法,语法是给写代码的人用的。如果用.net的“反编译”工具的朋友会知道,你用while语句写了一段代码,然后编译生成程序集,再用工具把代码“反”出来,此时你会发现,你原来写的是while语句,但出来的是for语句,道理是一样的,“反编译”工具只关心代码的执行逻辑,而不是语法。所以,你自然无法用 CodeDom 来生成var关键字来声明变量,也无法生成用 Lambda 表达式表示的方法,也不能生成仅有get和set的属性定义语法。

阅读更多

[转载]细说CodeDom(7):索引器

作者:老周,原文地址

开始正题之前,先补充一点前面的内容。

在方法中,如果要引用方法参数,前面的示例中,老周使用的是 CodeVariableReferenceExpression 类,它用于引用变量,也适用于引用方法参数。除了这个类,还可以使用 CodeArgumentReferenceExpression 类,这个类是专为方法参数引用而设计,其实用起来也和变量引用一样。请看看下面的例子。

阅读更多

[转载]细说CodeDom(6):方法参数

作者:老周,原文地址

本文老周就给大伙伴们介绍一下方法参数代码的生成。

在开始之前,先补充一下上一篇烂文的内容。在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作,后来发现是可以的。不过啊,MemberAttributes 枚举有些情况下不那么好弄,最典型的就是要生成抽象类的时候,反正老周试了很久,用MemberAttributes枚举不能顺利生成抽象类。

阅读更多

[转载]细说CodeDom(5):类型成员

作者:老周,原文地址

前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员。

咱们都知道,常见的类型成员,比如字段、属性、方法、事件。表示代码成员的类型与 CodeTypeDeclaration 类有着共同的基类—— CodeTypeMember。毕竟类型也好,类型成员也好,都有共同特征。

阅读更多

[转载]细说CodeDom(4):类型定义

作者:老周,原文地址

上一篇文章中说了命名空间,你猜猜接下来该说啥。是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了。

CLR的类型通常有这么几种:类、接口、结构、枚举、委托。是这么几个,应该没有漏掉的吧。

定义类型,除了委托外都可以用 CodeTypeDeclaration 类完成。CodeNamespace类公开一个Types集合,定义的类型必须添加到这个集合中,才能与命名空间关联。

阅读更多

[转载]细说CodeDom(2):表达式、语句

作者:老周,原文地址

在上一篇文章中,老周厚着脸皮给大伙介绍了代码文档的基本结构,以及一些代码对象与CodeDom类型的对应关系。

在评论中老周看到有朋友提到了 Emit,那老周就顺便提一下。严格上说,Emit并不是针对代码文档生成和编译而设计的,Emit一方面可以实时发出 IL 指令,另一方面也支持动态程序集,即可以在运行时创建程序集,并可以定义类型,然后可以执行。而CodeDom所针对的是代码文档的生成和编译,所以说,是有所不同的。

阅读更多

[转载]细说CodeDom(1):结构大观

作者:老周,原文地址

CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧。DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了。如果你从来没接触过 CodeDom,你大概可以根据这个名字,推断它应该和代码文档模型有关。

这推断是靠谱的,CodeDom的功能,老周厚着脸皮把它归结为两大部分:

  1. 生成代码文档。这个听起来很玄?不玄,就是咱们在VS里常常耍的代码生成,比如你添加了一个服务引用,VS会帮你生成一个客户端代理类。
  2. 动态编译程序集。这个也好懂,就是动态编译。
阅读更多

[译]Roslyn – 如何创建可调试的自定义脚本语言

作者:MICHAŁ KOMOROWSKI 27/10/2016 原文链接

不久前,我决定在Cakebuild上玩一些游戏。 这是一个构建自动化工具/系统,可让您使用C#域特定语言编写构建脚本。 而且,可以在Visual Studio中调试这些脚本。 有趣的是,Cake脚本既不是“普通” C#文件,也不会添加到项目(csproj)中。 我很好奇它是如何实现的,这是我分析的结果。 我将告诉您如何创建一种简单的可调试脚本语言。 通过可调试,我的意思是可以像使用C#中的任何“常规”程序一样,在Visual Studio中以我们的语言调试脚本。 Cakebuild使用Roslyn,即Microsft提供的编译器作为服务,我们将做同样的事情。

阅读更多

Flexsim最短路径算法50行代码搞定Floyd(弗洛伊德)

此算法由Robert W. Floyd(罗伯特·弗洛伊德)于1962年发表在“Communications of the ACM”上。同年Stephen Warshall(史蒂芬·沃舍尔)也独立发表了这个算法。Robert W.Floyd这个牛人是朵奇葩,他原本在芝加哥大学读的文学,但是因为当时美国经济不太景气,找工作比较困难,无奈之下到西屋电气公司当了一名计算机操作员,在IBM650机房值夜班,并由此开始了他的计算机生涯。此外他还和J.W.J. Williams(威廉姆斯)于1964年共同发明了著名的堆排序算法HEAPSORT。堆排序算法我们将在第七章学习。Robert W.Floyd在1978年获得了图灵奖。——引用自【Angel Kitty】博客

本代码同时还参考了【火星十一郎】的博客上写了一篇关于最短路径算法的介绍。废话不多说,按照惯例直接上代码:

阅读更多

propnotification代码片段

之前习惯了使用prop 和 propfull 代码片段, 为了MVVM架构就经常需要对ViewModel类型的 NotifyProperty 补充set方法,为了减少工作量,提高“搬砖”效率,我添加了下面的代码片段,注意需要实现 INotifyPropertyChanged 接口。

阅读更多

CShape&WPF笔记

问题:调试正常,编译exe后无法正常运行(界面不显示)

经过排查,确认了是数据绑定的原因,有一种情况,当绑定源的属性为 {get {…}, private set{…} } 或者 {get {…}, protect set{…} } 时。若绑定模式为TwoWay就会导致这个问题。

阅读更多

实现MVVM的两个基础类

NotificationObject类:

它实现了 InotifyPropertyChanged 接口, WPF 正是基于 PropertyChanged 委托实现绑定的。以后我们在业务需要设计的 ViewModel 派生自该类,例如 StudentViewModel 对于需要绑定的属性ID,调用下面的代码实现(例子):

阅读更多