- 浏览: 3048163 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (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分享的概要
之前在将ANTLR生成的.tokens文件重格式化(C#版),我把一个简单的对文本文件的匹配和排序程序用C#实现出来,并且与同系列文章中的Ruby和C++实现做了对比。当时我用到了C# 3.0的一些新特性来展现C#的简洁性,例如Lambda表达式之类。不过最近在读Jon Skeet编写、Manning出版的C# in Depth一书时发觉C# 3.0还有个很好的功能:自动生成的属性。
在用Java或者C#写程序的时候,许多guideline都建议不要直接暴露对象内部状态的变量,而是提供accessor/modifier(getter/setter)方法来提供对这些变量的访问。但有许多时候这些访问方法的逻辑是微不足道的(trivial),单纯就是把变量给包装了一下:
这种代码在POJO里十分常见但又没什么好办法避免。除非真的把域写成public的,但那样有潜在的缺陷就是了。
在C#里这个状况稍微好些,可以用专门的语法来把访问方法组织在一起,称为属性:
虽然写的代码稍微短了点,但这种没什么实际作用的代码还是占了很多行。
在C++/CLI里有自动生成的属性:
编译器会为这种属性自动生成一个私有变量来保存其状态,而不用我们手动指定。省了不少键盘输入,同时也减少了出错的机会。
Ruby对这种问题能通过元编程很好得解决:
在C# 3.0中,这个问题终于也有类似C++/CLI的解决办法了:同样是自动生成的属性。只要写一个非抽象的省略了get和set方法体的属性,编译器就能自动生成一个私有变量来对应这个属性。
非常方便。并且,对get和set单独指定可访问性的能力依然存在。例如说如果某个属性对外是只读的,那么写成:
就行。
注意到C# 3.0的自动生成的属性的语法:必须同时指定get和set,而不能只写其中一个。因此能够单独指定可访问性的特点就非常重要了。
在处理ANTLR的.tokens文件那篇里,我定义了一个struct来保存数据:
这里的两个属性都很明显是trivial的,用自动生成的属性是最好不过了。换成这样:
注意到我把原本定义为struct的这个类型改成class了。在C# 3.0中,自动生成的属性在struct中使用有个小小的诡异的地方:要在某个struct里使用自动生成的属性,所有构造器都必须调用无参数版本的构造器,这样编译器才能够确认所有的成员变量都被确定性赋值过。我们无法直接对自动生成的域赋值,因为不知道它的名字;而在所有的域都被赋值之前我们无法使用属性。
在这个例子里要继续使用struct的话,代码写成这样就行:
在Web开发的时候Model层里,许多纯粹的数据实体类的代码量都可以减少了……即便用代码生成器,生成出来的代码还是得维护,能有更简洁的语法总是件好事。
在用Java或者C#写程序的时候,许多guideline都建议不要直接暴露对象内部状态的变量,而是提供accessor/modifier(getter/setter)方法来提供对这些变量的访问。但有许多时候这些访问方法的逻辑是微不足道的(trivial),单纯就是把变量给包装了一下:
class Foo { private String bar; public String getBar() { return this.bar; } public void setBar(String bar) { this.bar = bar; } }
这种代码在POJO里十分常见但又没什么好办法避免。除非真的把域写成public的,但那样有潜在的缺陷就是了。
在C#里这个状况稍微好些,可以用专门的语法来把访问方法组织在一起,称为属性:
class Foo { private string _bar; public string Bar { get { return _bar; } set { _bar = value; } } }
虽然写的代码稍微短了点,但这种没什么实际作用的代码还是占了很多行。
在C++/CLI里有自动生成的属性:
class Foo { public: property String^ Bar; }
编译器会为这种属性自动生成一个私有变量来保存其状态,而不用我们手动指定。省了不少键盘输入,同时也减少了出错的机会。
Ruby对这种问题能通过元编程很好得解决:
class Foo attr_accessor :bar def initialize @bar = "" end end
在C# 3.0中,这个问题终于也有类似C++/CLI的解决办法了:同样是自动生成的属性。只要写一个非抽象的省略了get和set方法体的属性,编译器就能自动生成一个私有变量来对应这个属性。
class Foo { public string Bar { get; set; } }
非常方便。并且,对get和set单独指定可访问性的能力依然存在。例如说如果某个属性对外是只读的,那么写成:
class Foo { public string Bar { get; private set; } }
就行。
注意到C# 3.0的自动生成的属性的语法:必须同时指定get和set,而不能只写其中一个。因此能够单独指定可访问性的特点就非常重要了。
在处理ANTLR的.tokens文件那篇里,我定义了一个struct来保存数据:
struct TokenNameValuePair { private string _name; private int _value; public TokenNameValuePair(string name, int value) { _name = name; _value = value; } public string Name { get { return _name; } } public int Value { get { return _value; } } }
这里的两个属性都很明显是trivial的,用自动生成的属性是最好不过了。换成这样:
class TokenNameValuePair { // notice the "class" keyword public string Name { get; private set; } public int Value { get; private set; } public TokenNameValuePair(string name, int value) { Name = name; Value = value; } }
注意到我把原本定义为struct的这个类型改成class了。在C# 3.0中,自动生成的属性在struct中使用有个小小的诡异的地方:要在某个struct里使用自动生成的属性,所有构造器都必须调用无参数版本的构造器,这样编译器才能够确认所有的成员变量都被确定性赋值过。我们无法直接对自动生成的域赋值,因为不知道它的名字;而在所有的域都被赋值之前我们无法使用属性。
在这个例子里要继续使用struct的话,代码写成这样就行:
struct TokenNameValuePair { public string Name { get; private set; } public int Value { get; private set; } public TokenNameValuePair(string name, int value) : this() { // calls this() Name = name; Value = value; } }
在Web开发的时候Model层里,许多纯粹的数据实体类的代码量都可以减少了……即便用代码生成器,生成出来的代码还是得维护,能有更简洁的语法总是件好事。
发表评论
-
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22390(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 3304之前正好发了些帖子是关于CLR里的委托的,然后看到老赵说事件也 ... -
要让CLR挂掉的话(第二弹)……
2009-09-04 03:26 12870(Disclaimer:如果需要转 ... -
要让CLR挂掉的话……
2009-09-02 16:53 4776(Disclaimer:如果需要转载请先与我联系。 作者:Re ... -
趣味编程:函数式链表的快速排序
2009-08-31 08:53 3444(恢复自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 2598悲剧啊……前几天有个同学不停问我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 1635原文作者: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 4056在前一帖里,我用到了下面三处Expression.Call() ... -
看到一个关于ref参数与多态的问题,记一下
2009-05-18 10:48 1941刚才读到Alan McGovern的一帖,问为什么形式参数是r ... -
C#的+=运算符两例
2009-05-06 18:18 2031刚偶尔看到了justjavac写的java解惑 - 半斤八两( ...
相关推荐
C# 3.0引入了匿名类型,这是一种在编译时自动生成类型的特性,允许开发者创建不具名的临时类型。匿名类型通常用于LINQ查询中,可以方便地存储查询结果,而无需显式声明类型。 ### 扩展方法 扩展方法是C# 3.0中的另...
2. 自动属性(auto-implemented properties):简化了属性的定义,如`public string Name { get; set; }`。 3. 静态类(static classes):不能实例化的类,所有成员都是静态的,确保资源安全。 总结来说,C# 3.0...
4. **自动实现的属性**:C# 3.0引入了自动实现的属性,简化了类的定义,尤其是对于数据绑定和简单数据存储场景,减少了冗余代码。 5. **对象和集合初始器**:这些特性允许开发者在声明变量时同时初始化它们,使得...
这些类型的实例在编译时会自动生成唯一的类名,主要用于临时数据存储和中间操作。 3. **自动属性**:自动属性减少了代码的冗余,使得声明简单属性时无需编写getter和setter方法。例如,`public string Name { get; ...
C# 3.0 是微软.NET Framework 3.5的一部分,是C#语言的一个重要版本,引入了许多新特性,使得编程更加简洁、高效。在这个入门系列中,我们将深入探讨C# 3.0的关键概念,帮助初学者快速掌握这门强大的编程语言。 1. ...
2. **匿名类型**:在C# 3.0中,开发人员可以创建不指定类型的对象,这些对象具有自动生成的私有成员和默认的get属性。匿名类型通常用于临时存储和处理数据,尤其在LINQ查询中。 3. **LINQ(Language Integrated ...
这样的声明会自动生成一个名为`Name`的私有字段,并提供相应的get和set访问器。这极大地减少了编写简单属性时所需的代码量,并提高了代码的可读性和简洁性。 #### 2. **对象初始化器(Object Initializers)** C#...
匿名类在代码中没有明确声明,而是由编译器在编译时自动生成。它们通常用于临时数据存储,特别是在LINQ查询中。当多个匿名类型具有相同的属性结构时,编译器会合并为一个类型,从而优化内存使用。 7. **LINQ ...
4. **自动属性**:C# 3.0简化了属性的声明,只需提供访问器(getter和setter),编译器会自动生成私有字段,减少了代码量。 5. **对象初始化器和集合初始化器**:这些特性使得在创建对象时可以同时设置属性值,对...
匿名类型会自动生成私有属性,其名称和类型来自于初始化时的表达式。 3. **自动属性**:简化了属性的声明,通过自动实现的字段减少了样板代码,提高了代码的可读性和简洁性。 4. **扩展方法**:允许将方法添加到已...
这些类型在编译时由编译器自动生成,其名称是不可见的,但具有自动属性,简化了临时数据的处理。 3. **自动属性**:自动属性简化了类属性的声明,通过使用`= default`或`= value`来初始化属性,减少了代码的冗余。 ...
5. **自动属性**:C# 3.0简化了属性的定义,自动属性无需提供私有字段,编译器会自动生成。如 `public string Name { get; set; }` 会生成一个私有字段来存储Name的值。 6. **对象初始器和集合初始器**:对象初始器...
4. **自动属性**:这一特性简化了类成员的声明,允许开发者只需指定属性的名称和类型,编译器会自动生成存取器。例如,`public int Age { get; set; }`,这使得代码更加简洁。 5. **匿名方法与Lambda表达式**:C# ...
这些类型的实例具有自动生成的私有成员和默认的无参数构造函数,通常用于临时存储和处理数据。例如,`new { Name = "John", Age = 30 }` 就是创建了一个匿名类型实例。 接着,C# 3.0中的 LINQ 是一个强大的特性,它...
4. **自动实现的属性**:C# 3.0支持自动实现的属性,即可以在声明属性时省略get和set访问器的实现,这简化了属性的定义,减少了样板代码。 5. **扩展方法**:扩展方法是一种静态方法,可以像实例方法一样被调用,但...
C# 3.0是.NET Framework 3.0的一部分,引入了一系列增强特性和语言改进,旨在提高开发效率和代码的可读性。...C# 3.0的这些改进也为后续版本中的特性打下了坚实的基础,比如C# 6.0中的异步编程模型和属性表达式等。
}` 就是一个自动属性,编译器会自动生成对应的私有字段和访问器。 5. **对象初始化器**: 对象初始化器使得创建和初始化对象变得更简单,允许在一行代码中完成。例如:`var customer = new Customer { Name = ...