- 浏览: 3052808 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (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分享的概要
刚偶尔看到了justjavac写的java解惑 - 半斤八两(一)和java解惑 - 半斤八两(二)。里面提到了Java的复合赋值运算符的两个陷阱:1) 复合赋值运算符有强制类型转换的语义;2) += 左侧必须是原始类型中的数字类型,或者是String类型。
JLS3e如是说:
核心就这么一句,后面还有一堆细节规定,有兴趣可以到官网阅读:JLS3e: 15.26.2 Compound Assignment Operators
读下来,只有当复合赋值运算符的左手边是数组,且数组元素类型是String时才有提到特别针对String的+=,在15.26.2的其它地方并没有提到justjavac说的第二个限制,怪哉。
ECMA-334如是说:
C#中复合赋值运算符比Java规定了更多的转换相关规则,不过还是可以很直观的理解:(注意上面用蓝色色高亮的那句)只有当x op y和x = y都是合法的时候,x op= y才是合法的。
也正是因为这样,所以justjavac提到的Java的两个陷阱在C#里都不存在:
1、编译错误:
不用像Java那样等到运行的时候再发现数据被剪了。
2、编译没问题,运行也没问题:
==================
从OpenJDK的邮件列表里挖个东西顺带放这儿:
JLS3e如是说:
Java Language Specification, 3rd Edition 写道
15.26.2 Compound Assignment Operators
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
核心就这么一句,后面还有一堆细节规定,有兴趣可以到官网阅读:JLS3e: 15.26.2 Compound Assignment Operators
读下来,只有当复合赋值运算符的左手边是数组,且数组元素类型是String时才有提到特别针对String的+=,在15.26.2的其它地方并没有提到justjavac说的第二个限制,怪哉。
ECMA-334如是说:
ECMA-334, 4th Edition 写道
14.14.2 Compound assignment
An operation of the form x op= y is processed by applying binary operator overload resolution (§14.2.4) as if the operation was written x op y. Then,
When the left operand of a compound assignment is a property access or indexer access, the property or indexer shall have both a get accessor and a set accessor. If this is not the case, a compile-time error occurs.
The second rule above permits x op= y to be evaluated as x = (T)(x op y) in certain contexts. The rule exists such that the predefined operators can be used as compound operators when the left operand is of type sbyte, byte, short, ushort, or char. Even when both arguments are of one of those types, the predefined operators produce a result of type int, as described in §14.2.6.2. Thus, without a cast it would not be possible to assign the result to the left operand.
The intuitive effect of the rule for predefined operators is simply that x op= y is permitted if both of x op y and x = y are permitted. [Example: In the following code
the intuitive reason for each error is that a corresponding simple assignment would also have been an error. end example]
[Note: Compound assignment operations support lifted operators. Since a compound assignment x op= y is evaluated as either x = x op y or x = (T)(x op y), the rules of evaluation implicitly cover lifted operators. end note]
14.14.3 Event assignment
If the left operand of a += or -= operator is an event, the expression is classified as an event access, and is evaluated as follows:
An operation of the form x op= y is processed by applying binary operator overload resolution (§14.2.4) as if the operation was written x op y. Then,
- If the return type of the selected operator is implicitly convertible to the type of x, the operation is evaluated as x = x op y, except that x is evaluated only once.
- Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x or the operator is a shift operator, then the operation is evaluated as x = (T)(x op y), where T is the type of x, except that x is evaluated only once.
- Otherwise, the compound assignment is invalid, and a compile-time error occurs.
When the left operand of a compound assignment is a property access or indexer access, the property or indexer shall have both a get accessor and a set accessor. If this is not the case, a compile-time error occurs.
The second rule above permits x op= y to be evaluated as x = (T)(x op y) in certain contexts. The rule exists such that the predefined operators can be used as compound operators when the left operand is of type sbyte, byte, short, ushort, or char. Even when both arguments are of one of those types, the predefined operators produce a result of type int, as described in §14.2.6.2. Thus, without a cast it would not be possible to assign the result to the left operand.
The intuitive effect of the rule for predefined operators is simply that x op= y is permitted if both of x op y and x = y are permitted. [Example: In the following code
byte b = 0; char ch = '\0'; int i = 0; b += 1; // Ok b += 1000; // Error, b = 1000 not permitted b += i; // Error, b = i not permitted b += (byte)i; // Ok ch += 1; // Error, ch = 1 not permitted ch += (char)1; // Ok
the intuitive reason for each error is that a corresponding simple assignment would also have been an error. end example]
[Note: Compound assignment operations support lifted operators. Since a compound assignment x op= y is evaluated as either x = x op y or x = (T)(x op y), the rules of evaluation implicitly cover lifted operators. end note]
14.14.3 Event assignment
If the left operand of a += or -= operator is an event, the expression is classified as an event access, and is evaluated as follows:
- The instance expression, if any, of the event access is evaluated.
- The right operand of the += or -= operator is evaluated, and, if required, converted to the type of the left operand through an implicit conversion (§13.1).
- An event accessor of the event is invoked, with argument list consisting of the value computed in the previous step. If the operator was +=, the add accessor is invoked; if the operator was -=, the remove accessor is invoked.
C#中复合赋值运算符比Java规定了更多的转换相关规则,不过还是可以很直观的理解:(注意上面用蓝色色高亮的那句)只有当x op y和x = y都是合法的时候,x op= y才是合法的。
也正是因为这样,所以justjavac提到的Java的两个陷阱在C#里都不存在:
1、编译错误:
static class Program { static void Main(string[] args) { byte b = 0; int i = 1; b += i; // error CS0266: 无法将类型“int”隐式转换为“byte”。存在一个显式转换(是否缺少强制转换?) } }
不用像Java那样等到运行的时候再发现数据被剪了。
2、编译没问题,运行也没问题:
using System; using System.Linq.Expressions; static class Program { static void Main(string[] args) { string s = "str: "; object obj = (Expression<Func<int, int>>) (x => x + 1); s += obj; obj += s; Console.WriteLine(s); // str: x => (x + 1) Console.WriteLine(obj); // x => (x + 1)str: x => (x + 1) } }
==================
从OpenJDK的邮件列表里挖个东西顺带放这儿:
引用
Changeset: f09d6a3521b1
Author: jjg
Date: 2008-03-06 10:07 -0800
URL: http://hg.openjdk.java.net/jdk7/hotspot-comp/langtools/rev/f09d6a3521b1
4741726: allow Object += String
Summary: remove code in line with restriction removed from JLS
Reviewed-by: mcimadamore
Contributed-by: michaelbailey0 at gmail.com
! src/share/classes/com/sun/tools/javac/comp/Attr.java
+ test/tools/javac/StringConversion2.java
- test/tools/javac/expression/ObjectAppend.java
Author: jjg
Date: 2008-03-06 10:07 -0800
URL: http://hg.openjdk.java.net/jdk7/hotspot-comp/langtools/rev/f09d6a3521b1
4741726: allow Object += String
Summary: remove code in line with restriction removed from JLS
Reviewed-by: mcimadamore
Contributed-by: michaelbailey0 at gmail.com
! src/share/classes/com/sun/tools/javac/comp/Attr.java
+ test/tools/javac/StringConversion2.java
- test/tools/javac/expression/ObjectAppend.java
发表评论
-
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22408(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 3312之前正好发了些帖子是关于CLR里的委托的,然后看到老赵说事件也 ... -
要让CLR挂掉的话(第二弹)……
2009-09-04 03:26 12879(Disclaimer:如果需要转 ... -
要让CLR挂掉的话……
2009-09-02 16:53 4785(Disclaimer:如果需要转载请先与我联系。 作者:Re ... -
趣味编程:函数式链表的快速排序
2009-08-31 08:53 3450(恢复自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 2603悲剧啊……前几天有个同学不停问我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 1639原文作者: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 4063在前一帖里,我用到了下面三处Expression.Call() ... -
看到一个关于ref参数与多态的问题,记一下
2009-05-18 10:48 1944刚才读到Alan McGovern的一帖,问为什么形式参数是r ... -
Nullable的诡异之处……
2009-04-02 20:52 1834原来Nullable type是null的时候,以它作为被调用 ...
相关推荐
以题目中的`EmployeeDetail`类为例,我们可以为这个类重载`+`运算符,使得两个`EmployeeDetail`对象相加时,创建一个新的`EmployeeCollection`对象,包含这两个员工的信息。这可以通过定义如下两个重载方法实现: `...
在订阅者类中,我们需要定义一个符合事件处理程序签名的方法,并使用`+=`运算符将其添加到事件中。当事件触发时,这个方法会被调用。 ```csharp public void OnMyEvent(object sender, EventArgs e) { // 处理...
然后,订阅者可以使用`+=`运算符连接到事件源的事件: ```csharp eventSource.MyEvent += OnMyEvent; ``` 触发事件时,只需调用事件委托即可: ```csharp MyEvent?.Invoke(this, new MyEventArgs(...)); ``` 在...
3. 最后,通过`+=`运算符将事件处理方法绑定到事件上,如`this.button1.Click += new System.EventHandler(this.button1_Click);`。 事件处理的工作流程是这样的:当事件触发时(例如用户点击按钮),系统会调用...
这套资源分为两卷,共计1200个实例,旨在帮助开发者深入理解和掌握C#的核心概念以及在项目开发中的实际应用技巧。 C#是一种由微软公司开发的面向对象的编程语言,它被广泛应用于Windows平台的软件开发、游戏开发、...
)等,还有赋值运算符(=、+=、-=、*=、/=、%=)。 4. **运算符优先级**:运算符的优先级决定了表达式的计算顺序,例如括号()具有最高优先级,然后是乘除(*)、加减(+),最后是赋值(=)。 5. **数据类型转换**:C#...
通过`+=`运算符,我们订阅了事件,并提供了一个匿名方法作为事件处理程序。 "C#实用编程百例(续1)"可能还会涵盖更多主题,如异常处理、多线程、文件I/O、网络编程、数据库访问等。每一道实例都将帮助你加深对C#...
创建委托实例之后,可以通过`+=`运算符将方法绑定到委托上: ```csharp MyDelegate myDelegate = new MyDelegate(MyMethod); myDelegate += MyAnotherMethod; myDelegate("Hello, Delegate!"); ``` 这里`MyMethod...
学习C#.NET首先要掌握C#的基本语法,包括变量、数据类型、运算符、控制结构(如if语句、for循环、while循环)、函数、类和对象等。 2. **.NET Framework**:它是微软开发的软件框架,提供了丰富的类库和运行时环境...
《C#开发实战1200例(第1卷)源码》是一个全面涵盖C#编程实践的资源集合,提供了1200个实例代码,旨在帮助开发者深入理解和掌握C#语言的核心特性和实际应用。这个资源包包含了两个RAR压缩文件,即MR12-25.rar和MR1-11....
《C#开发实战1200例(第2卷)源码》是针对C#编程语言的一本实战性教程,其核心在于通过大量的实例来帮助读者深入理解和掌握C#编程技术。这本书的第二卷源码提供了丰富的代码示例,覆盖了C#语言的各个方面,包括基础...
1. **基础语法**:C#的基础包括变量、数据类型、运算符、流程控制(如if语句、for循环、while循环)、函数、类与对象等。这些是所有编程语言的基础,也是初学者的入门点。 2. **面向对象编程**:C#作为一门面向对象...
在 C# 中,new 运算符和 new 修饰符是两个不同的概念。new 运算符用于创建对象和调用构造函数,而 new 修饰符用于隐藏基类成员的继承成员。了解这两个概念的用法和应用场景对于编写高效、灵活的 C# 代码非常重要。 ...
1. **C#基础语法**:C#是一种强类型、面向对象的语言,学习之初会接触到变量声明、数据类型(如int, string, bool等)、运算符、控制流(if-else, switch, for, while等)以及函数的使用。 2. **类与对象**:C#是...
- 常见的运算符还包括算术运算符(加减乘除等)、赋值运算符(`=`, `+=`, `-=`等)、关系运算符(`==`, `!=`, `, `>`等)和逻辑运算符(`&&`, `||`, `!`等)。 5. **案例分析** - 例3-1展示了不同数值类型的赋值...
《C#实用编程百例》是一本专注于C#编程实践的书籍,其光盘源码包含了大量的实例,旨在帮助读者深入理解和掌握C#语言的核心概念和技术。这些实例覆盖了C#编程的各个方面,从基础语法到高级特性,是学习和提升C#编程...
1. **C#基础**:书中首先会介绍C#的基础语法,包括变量、数据类型、运算符、控制流(如if语句、switch语句、循环)、函数、类与对象等。这些是学习任何面向对象语言的基石,掌握它们能让你更好地理解C#程序的构造。 ...
在C#编程语言中,`==`运算符和`Equals()`方法是用来比较对象或值类型是否相等的两种常见方式,但它们之间存在着显著的区别。本文将深入探讨这两种比较方式的工作原理及其应用场景。 首先,`==`运算符是C#中的一个...
本文将以“勾月计算器程序”为例,深入解析C#语言中的基本运算逻辑、switch-case-break语句的运用以及程序设计的思路。 首先,让我们关注这个程序的核心功能——加、减、乘、除运算。在C#中,这些基本的算术运算...
C#是一种面向对象的编程语言,广泛应用于Windows应用开发,尤其是在构建桌面应用程序时,如本例中的计算器。 四则运算,即加法、减法、乘法和除法,是基础数学中的基本运算。在C#中实现这些运算通常涉及使用算术...