- 浏览: 3023074 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (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分享的概要
在前一帖里,我用到了下面三处Expression.Call()的调用。它们都需要一个MethodInfo参数来指定调用的方法,我就通过直观的反射来得到这些参数。
其中,在注释1的地方我要实现的是list.GetEnumerator()的效果,list是一个IOrderedEnumerable<int>类型的变量;
在注释2的地方我要实现的是iter.MoveNext(),iter是一个IEnumerator<int>类型的变量,由ParameterExpression类型的vIter提供。
要是把这两处代码改一下,变成这样:
也就是获取变量的类型然后对其做反射来查找方法,就会……在运行时得到NullReferenceException。为什么?
仔细观察可以留意到,IOrderedEnumerable<T>中GetEnumerator()方法是显式实现IEnumerable<T>的;IEnumerator<T>的MoveNext()是显式实现IEnumerator的。
在C#中,如果显式实现一个接口,那么显式实现的方法就会被标记为私有的。Type.GetMethod()方法默认只寻找公有成员,于是就出错了。
C#语言规范里有这么一段:
总之要用反射找这样的显式实现接口的方法,在GetMethod()的时候记得带上BindingFlags.NonPublic没错的~
P.S. CLI里并没有“显式实现接口”的概念,只有mapped和implicit实现的区别。这里提到的显式实现接口是C#语言的规则而已。
P.P.S Chris Brumme以前写过一帖详细描述了显式实现接口生成的代码,Interface Layout。CLR要理解C#的显式接口实现,关键在于显式实现接口方法的方法体里的.override信息。
// 1 Expression.Call( Expression.Constant(list), typeof(IEnumerable<int>).GetMethod("GetEnumerator")) // 2 Expression.Call( vIter, typeof(IEnumerator).GetMethod("MoveNext")) // 3 Expression.Call( typeof(Console).GetMethod("WriteLine", new[] { typeof(int) }), new[] { vI })
其中,在注释1的地方我要实现的是list.GetEnumerator()的效果,list是一个IOrderedEnumerable<int>类型的变量;
在注释2的地方我要实现的是iter.MoveNext(),iter是一个IEnumerator<int>类型的变量,由ParameterExpression类型的vIter提供。
要是把这两处代码改一下,变成这样:
// 1 Expression.Call( Expression.Constant(list), list.GetType().GetMethod("GetEnumerator")) // 2 Expression.Call( vIter, vIter.Type.GetMethod("MoveNext"))
也就是获取变量的类型然后对其做反射来查找方法,就会……在运行时得到NullReferenceException。为什么?
仔细观察可以留意到,IOrderedEnumerable<T>中GetEnumerator()方法是显式实现IEnumerable<T>的;IEnumerator<T>的MoveNext()是显式实现IEnumerator的。
在C#中,如果显式实现一个接口,那么显式实现的方法就会被标记为私有的。Type.GetMethod()方法默认只寻找公有成员,于是就出错了。
C#语言规范里有这么一段:
C# Language Specification 写道
Explicit interface member implementations have different accessibility characteristics than other members. Because explicit interface member implementations are never accessible through their fully qualified name in a method invocation or a property access, they are in a sense private. However, since they can be accessed through an interface instance, they are in a sense also public.
总之要用反射找这样的显式实现接口的方法,在GetMethod()的时候记得带上BindingFlags.NonPublic没错的~
P.S. CLI里并没有“显式实现接口”的概念,只有mapped和implicit实现的区别。这里提到的显式实现接口是C#语言的规则而已。
P.P.S Chris Brumme以前写过一帖详细描述了显式实现接口生成的代码,Interface Layout。CLR要理解C#的显式接口实现,关键在于显式实现接口方法的方法体里的.override信息。
发表评论
-
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22283(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 3261之前正好发了些帖子是关于CLR里的委托的,然后看到老赵说事件也 ... -
要让CLR挂掉的话(第二弹)……
2009-09-04 03:26 12783(Disclaimer:如果需要转 ... -
要让CLR挂掉的话……
2009-09-02 16:53 4710(Disclaimer:如果需要转载请先与我联系。 作者:Re ... -
趣味编程:函数式链表的快速排序
2009-08-31 08:53 3397(恢复自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 2563悲剧啊……前几天有个同学不停问我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 1605原文作者: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 ... -
看到一个关于ref参数与多态的问题,记一下
2009-05-18 10:48 1920刚才读到Alan McGovern的一帖,问为什么形式参数是r ... -
C#的+=运算符两例
2009-05-06 18:18 1986刚偶尔看到了justjavac写的java解惑 - 半斤八两( ... -
Nullable的诡异之处……
2009-04-02 20:52 1799原来Nullable type是null的时候,以它作为被调用 ...
相关推荐
2.2.2 实现接口与显式实现接口 2.2.3 C#的实现继承 2.2.4 继承和重用 2.3 框架宿主程序设计与实现 2.3.1 属性——合理冲破私有变量访问限制 2.3.2 动手——从宿主程序开始 2.4 框架通信契约设计 2.4.1 ...
11.4 显式实现事件 第12章 泛型 12.1 Framework类库中的泛型 12.2 Wintellect的Power Collections库 12.3 泛型基础结构 12.3.1 开放和封闭类型 12.3.2 泛型类型和继承 12.3.3 泛型类型同一性 12.3.4 代码...
4.1.7 语句与方法调用的比较 4.2 方法的声明 4.2.1 参数声明 4.2.2 方法返回值声明 4.3 uslng指令 4.4 main()的返回值和参数 4.5 参数 4.5.1 值参数 4.5.2 引用参数 4.5.3 输出参数 4.5.4 参数数组 ...
显式接口实现(C# 编程指南) 并且这两个接口包含具有相同签名的成员, 那么在类中实现该成员将 如果类实现两个接口, 导致两个接口都使用该成员作为它们的实现。 例如: interface IControl ...
实现接口 145 访问接口方法 154 重定义接口的实现 162 显式接口实现 166 第9章 数组、索引器与集合 176 数组 176 foreach语句 181 索引器 197 集合接口 206 约束 210 List<T> 215 队列 226 栈 229 字典 232 第10章 ...
11.4 显式实现事件 第12章 泛型 12.1 Framework类库中的泛型 12.2 Wintellect的Power Collections库 12.3 泛型基础结构 12.3.1 开放和封闭类型 12.3.2 泛型类型和继承 12.3.3 泛型类型同一性 12.3.4 代码...
11.4 显式实现事件 第12章 泛型 12.1 Framework类库中的泛型 12.2 Wintellect的Power Collections库 12.3 泛型基础结构 12.3.1 开放和封闭类型 12.3.2 泛型类型和继承 12.3.3 泛型类型同一性 12.3.4 代码...
实现接口 145 访问接口方法 154 重定义接口的实现 162 显式接口实现 166 第9章 数组、索引器与集合 176 数组 176 foreach语句 181 索引器 197 集合接口 206 约束 210 List<T> 215 队列 226 栈 229 字典 232 第10章 ...
实现接口 145 访问接口方法 154 重定义接口的实现 162 显式接口实现 166 第9章 数组、索引器与集合 176 数组 176 foreach语句 181 索引器 197 集合接口 206 约束 210 List<T> 215 队列 226 栈 229 字典 232 第10章 ...
11.4 显式实现事件 第12章 泛型 12.1 Framework类库中的泛型 12.2 Wintellect的Power Collections库 12.3 泛型基础结构 12.3.1 开放和封闭类型 12.3.2 泛型类型和继承 12.3.3 泛型类型同一性 12.3.4 代码...
在这种情况下,普通动态绑定是不可靠的,因为它在使用显式实现的接口成员时会失败。 Uncapsulator类似于类固醇上的 ,它基于Joseph Albahari编写的的内置功能。 入门 可以通过同名的NuGet软件包下载解封装器。 ...
写一个方法,实现字符串的反转,如:输入abc,输出cba 写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出bbbhhtccc。 3.数据类型之间的转换 如何将数值型字符转换为数字(Integer,Double) 如何将数字...
10.6 显式实现接口 190 10.7 小结 194 10.8 习题 194 第三篇 应用技术篇 第11章 异常处理 200 11.1 异常处理的基础 200 11.1.1 什么是异常 200 11.1.2 未捕获异常的后果 200 11.1.3 常用异常 201 11.1.4 异常处理 ...
接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它...
4.1.7 语句与方法调用的比较 108 4.2 方法的声明 108 4.2.1 形式参数声明 109 4.2.2 方法返回类型声明 110 4.3 using指令 111 4.4 Main()的返回值和参数 114 4.5 方法的参数 116 4.5.1 ...