- 浏览: 3049624 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
读了Eric Lippert的这帖:High maintenance之后,心里一阵寒——我自己写的代码里就有几乎一模一样的逻辑。
Eric的帖里举的不好的例子:
我的代码:
事实上我的还更糟糕一些,没做null检查。写扩展方法的时候我总是写着写着就忘了:扩展方法不是成员方法,作为“this”的参数需要做null检查。
Eric对他所举的例子指出了几个不足:
1、null检查不是在方法调用时执行,而是在迭代器第一次移动的时候才执行的;
2、while循环在一行塞了太多逻辑,可以分开来写;
3、通过BaseStream来改变了底下的流的位置,不符合习惯上对流的使用方式;
4、调用者需要知道太多细节,例如必须知道何时这个迭代器结束了,在结束后由调用者来关闭流;
……等。
第4点我在写我那个程序时也知道这里有问题,但没想出好的解决办法。假如我就是要特意把流设置到某个位置之后再调用Lines(),该怎么办呢?或者说假如原本就不存在一个实际文件(例如stdin),那就无法用文件名来指定参数了,又怎么办呢?
于是在Stream的ownership上我还是得再思考一下才行。这篇主要是要提醒自己C#的generator的一个重要特性:
带有yield关键字的方法(也就是generator),其方法体在generator被调用时是不会被执行的;只有当其返回的iterator的MoveNext()方法被初次调用时才会执行。
举例来说,这样:
输出的结果会是:
了解C#的generator的实现方式就不难理解这个行为的来源。C#的generator实际上是个由编译器自动生成的实现了IEnumerable<T>接口的有限状态机。也就是说generator里实际上只有一个return new ...,或许还会有些参数赋值,却没有任何别的内容。源码里写在generator里的逻辑都生成到了那个有限状态机对象里,也就是外界看到的迭代器里。如果要对参数做检查,恐怕还就是Eric说的,提供一个公有方法作为接口,在里面检查参数的正确性,然后再调用一个私有的generator来完成实际迭代工作。
用FooGenerator的例子说,假如max小于0是不符合要求的,那么应该这样写:
Eric的帖里举的不好的例子:
public static class StreamReaderExtensions { public static IEnumerable<string> Lines(this StreamReader reader) { if (reader== null) throw new ArgumentNullException("reader"); reader.BaseStream.Seek(0, SeekOrigin.Begin); string line; while ((line = reader.ReadLine()) != null) yield return line; } }
我的代码:
/// <summary> /// Reads the stream as lines of strings from the current /// position to the end of the stream. /// </summary> /// <param name="reader">the stream to read from</param> /// <returns>An enumerator of the lines of strings.</returns> public static IEnumerable<string> Lines( this StreamReader reader ) { for ( var line = reader.ReadLine( ); null != line; line = reader.ReadLine( ) ) { yield return line; } }
事实上我的还更糟糕一些,没做null检查。写扩展方法的时候我总是写着写着就忘了:扩展方法不是成员方法,作为“this”的参数需要做null检查。
Eric对他所举的例子指出了几个不足:
1、null检查不是在方法调用时执行,而是在迭代器第一次移动的时候才执行的;
2、while循环在一行塞了太多逻辑,可以分开来写;
3、通过BaseStream来改变了底下的流的位置,不符合习惯上对流的使用方式;
4、调用者需要知道太多细节,例如必须知道何时这个迭代器结束了,在结束后由调用者来关闭流;
……等。
第4点我在写我那个程序时也知道这里有问题,但没想出好的解决办法。假如我就是要特意把流设置到某个位置之后再调用Lines(),该怎么办呢?或者说假如原本就不存在一个实际文件(例如stdin),那就无法用文件名来指定参数了,又怎么办呢?
于是在Stream的ownership上我还是得再思考一下才行。这篇主要是要提醒自己C#的generator的一个重要特性:
带有yield关键字的方法(也就是generator),其方法体在generator被调用时是不会被执行的;只有当其返回的iterator的MoveNext()方法被初次调用时才会执行。
举例来说,这样:
using System; using System.Collections.Generic; static class Program { static IEnumerable<int> FooGenerator( int max ) { Console.WriteLine( "Starting enumerator" ); for ( var i = 0; i < max; ++i ) { yield return i; } } static void Main( string[ ] args ) { var list = FooGenerator( 3 ); Console.WriteLine( "After Foo(), before foreach" ); foreach ( var i in list ) { Console.WriteLine( i ); } } }
输出的结果会是:
After Foo(), before foreach Starting enumerator 0 1 2
了解C#的generator的实现方式就不难理解这个行为的来源。C#的generator实际上是个由编译器自动生成的实现了IEnumerable<T>接口的有限状态机。也就是说generator里实际上只有一个return new ...,或许还会有些参数赋值,却没有任何别的内容。源码里写在generator里的逻辑都生成到了那个有限状态机对象里,也就是外界看到的迭代器里。如果要对参数做检查,恐怕还就是Eric说的,提供一个公有方法作为接口,在里面检查参数的正确性,然后再调用一个私有的generator来完成实际迭代工作。
用FooGenerator的例子说,假如max小于0是不符合要求的,那么应该这样写:
public static IEnumerable<int> FooGenerator( int max ) { if ( 0 > max ) { throw new ArgumentException( "Number must be non-negative", "max" ); } return FooGeneratorCore( max ); } private static IEnumerable<int> FooGenerator( int max ) { for ( var i = 0; i < max; ++i ) { yield return i; } }
发表评论
-
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22397(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
对象的重量
2011-08-21 17:15 0http://domino.research.ibm.com/ ... -
GetCustomAttribute()每次都返回新Attribute实例
2009-11-10 10:30 0Jeffrey Zhao: 一次失败的尝试(上):原来GetC ... -
委托与方法和隐藏参数
2009-09-07 15:32 3306之前正好发了些帖子是关于CLR里的委托的,然后看到老赵说事件也 ... -
要让CLR挂掉的话(第二弹)……
2009-09-04 03:26 12873(Disclaimer:如果需要转 ... -
要让CLR挂掉的话……
2009-09-02 16:53 4777(Disclaimer:如果需要转载请先与我联系。 作者:Re ... -
趣味编程:函数式链表的快速排序
2009-08-31 08:53 3445(恢复自2009-08-28的备份 ... -
事件处理器导致内存泄漏
2009-08-25 15:03 0Memory leak via event handlers ... -
C# 3.0的类型推导
2009-08-23 12:24 0Howard Dierking: Lambda, Lambda ... -
把lock的意思给弄混了 T T
2009-08-20 17:49 2600悲剧啊……前几天有个同学不停问我Java里的同步问题,今天写C ... -
把IEnumerable<T>和IObservable<T>粘起来?
2009-07-23 03:02 0Channel 9: Expert to Expert: Br ... -
Scott Peterson: Variance, Thy Name is Ambiguity
2009-07-01 23:49 1636原文作者:Scott Peterson 原文地址:http:/ ... -
void无法协变
2009-06-30 11:17 0Eric Lippert The void is invari ... -
同一个表达式算出来的浮点数结果会不相等?
2009-05-30 03:27 0浮点数有很多可把玩的地方。例如下面这段C程序: #includ ... -
C#开始默认引用Microsoft.CSharp.dll
2009-05-20 16:14 0记得VB6的运行时么?留意到VB.NET的程序都需要额外的VB ... -
反射与显式实现接口的方法
2009-05-20 11:43 4059在前一帖里,我用到了下面三处Expression.Call() ... -
看到一个关于ref参数与多态的问题,记一下
2009-05-18 10:48 1941刚才读到Alan McGovern的一帖,问为什么形式参数是r ... -
C#的+=运算符两例
2009-05-06 18:18 2034刚偶尔看到了justjavac写的java解惑 - 半斤八两( ...
相关推荐
生成的C#类可以直接被`Newtonsoft.Json`库(或.NET Core中的`System.Text.Json`库)用于序列化和反序列化,实现JSON数据和C#对象之间的转换。 例如,假设有一个如下的JSON数据: ```json { "name": "John Doe", ...
【描述】:CodeGenerator是一款C#编写的实用工具,它的主要功能是从数据库中提取表结构信息,并根据这些信息自动生成对应的代码,极大地提高了开发效率,减少了手动编写重复代码的工作量。 【详细知识点】: 1. **...
在C#中,可以使用`yield return`关键字来实现Generator的返回。 以下是一个简化的C#代码示例,展示了如何使用Generator来解决Hanoi塔问题: ```csharp public static IEnumerable<string> Hanoi(int n, char from,...
在本篇文章中,我们将深入探讨MyBatis Generator的使用方法、主要功能以及如何结合MyBatis框架来提升开发效率。 一、MyBatis Generator简介 MyBatis Generator是一个基于Java的代码生成器,它能够根据数据库表结构...
本篇文章将详细介绍如何使用`FreeSql.Generator`这一工具来从MySQL数据库自动生成C#实体类。 #### 一、安装FreeSql.Generator 在开始使用`FreeSql.Generator`之前,首先需要将其安装到您的开发环境中。安装步骤...
这些表会被映射为C#类,每个字段对应类中的一个属性。 3. 生成配置:工具通常提供一些自定义选项,例如是否生成注释、是否忽略特定字段、属性的数据类型转换等,以满足不同开发者的编码风格和需求。 4. 输出结果:...
- Generator中的错误会被自动抛出,可以在外层捕获。 - 示例: ```javascript app.get('/', function*(req, res) { try { var result = yield someAsyncTask(); res.send(result); } catch (err) { res....
在JavaScript中,Generator是一种特殊的函数,它的主要特性是可以暂停和恢复执行。Generator函数的返回值是一个迭代器对象,使用yield关键字来暂停函数的执行,并返回一个值;再次调用迭代器的next()方法时,...
赠送jar包:mybatis-generator-core-1.3.7.jar; 赠送原API文档:mybatis-generator-core-1.3.7-javadoc.jar; 赠送源代码:mybatis-generator-core-1.3.7-sources.jar; 赠送Maven依赖信息文件:mybatis-generator-...
OpenAPI Generator则是这个规范的实用工具,通过解析规范文件(通常是.yaml或.json格式),它可以生成多种编程语言的SDK(Software Development Kit),如Java、Python、C#、JavaScript等,这样开发者就可以直接在...
3. **脚本语言**:LoadRunner使用VU Generator(VuGen)中的内置脚本语言——Vuser Language(VuScript)。VuScript类似于C语言,允许用户自定义函数和变量,进行条件判断和循环控制。 4. **参数化**:为了模拟真实...
Msc-generator是一款用于从文本描述中绘制各种图表的工具,它的版本为6.1.0,更新于2017年11月3日。这款工具可以生成多种类型的图表,包括信号图、流程图、块图等,每种图表都有其特定的用途和特点。为了更好地理解...
在这个例子中,`fetch`操作被`yield`暂停,外部可以通过`next`方法传递结果给Generator,使得Generator能够继续执行。 接下来,我们讨论js进程中断。在JavaScript中,由于其单线程特性,一旦开始执行,无法直接中断...
首先,你需要在项目中引入MyBatis Generator的依赖。如果是Maven项目,可以在pom.xml中添加以下依赖: ```xml <groupId>org.mybatis.generator <artifactId>mybatis-generator-core <version>1.4.2 ``` 接...
MyBatis Generator是一款强大的逆向工程工具,它能够根据数据库中的表自动生成对应的Java实体类、Mapper接口和XML配置文件,极大地提高了开发效率。在给定的标题中,“mybatis逆向工具generator,中文注释,Byte改...
在引入form-generator项目时,需要复制form-generator项目的components文件夹下的全部文件、uits文件夹下的所有文件以及views文件夹下全部文件到自己项目中,styles文件夹下全部文件复制到自己工程,icons文件夹下...
如果是eclipse工具,直接生成的,则替换:plugins/org.mybatis.generator.core_1.3.2*****.jar,如果是其他方式则直接替换掉官方的mybatis-generator-core1.3.2.jar即可
FFmpeg库被许多编程语言所支持,包括C#。本篇将深入探讨如何在C#环境下利用FFmpeg进行视频处理以及播放视频。 首先,`C# ffmpeg.autogen`是指将FFmpeg的C语言接口自动生成为C#可用的接口,以便于在C#项目中调用...
做个记号。自己收集使用。 你也可通过以下链接下载 https://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313/