- 浏览: 3049070 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (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 22395(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 12872(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 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 ... -
看到一个关于ref参数与多态的问题,记一下
2009-05-18 10:48 1941刚才读到Alan McGovern的一帖,问为什么形式参数是r ... -
C#的+=运算符两例
2009-05-06 18:18 2032刚偶尔看到了justjavac写的java解惑 - 半斤八两( ... -
Nullable的诡异之处……
2009-04-02 20:52 1829原来Nullable type是null的时候,以它作为被调用 ...
相关推荐
实现接口的类需要提供接口中所有成员的具体实现。例如: ```csharp public class MyClass : IMyInterface { public void MyMethod() { // 实现细节 } public int GetValue() { return 10; // 示例返回值 }...
在这个“21-04-03_FactoryPattern(001_在工厂模式下以通过接口结合列表、泛型和反射等方式实现指定类型的实例化操作_控制台)”案例中,我们将探讨如何利用接口、泛型和反射等技术来进一步增强工厂模式的功能。...
- 类通过关键字`implements`来实现接口,并且必须提供接口中所有抽象方法的实现。 - 如果类不提供接口中某个抽象方法的实现,那么该类必须声明为抽象类(abstract class)。 - 实现接口时,可以重写接口中默认...
接口也不能直接实例化,但所有成员都必须由实现类显式实现。 2. **继承性:** 抽象类支持单一继承,即一个类只能继承一个抽象类;接口支持多重继承,即一个类可以实现多个接口。 3. **成员实现:** 抽象类可以包含已...
使用Go-grpcall,开发者不再需要显式地实例化存根,只需提供服务名和方法名,即可动态生成并执行请求。 Go-grpcall的一个重要应用场景是制作grpc代理模式中间件,例如grpc-gateway。grpc-gateway是一个反向代理,它...
在Java和.NET等面向对象的语言中,反射是强大的工具,可以用于实现元编程,即在程序运行时动态地创建对象、调用方法、访问字段等。 在动态调用WebService时,反射可以用来获取WebService的接口信息,动态地创建服务...
在Java编程语言中,反射是一种强大的机制,它允许我们在运行时检查类、接口、字段和方法的信息,并且能够在不知道对象具体类型的情况下调用其方法或访问其属性。反射是Java提供的一种动态类型功能,这对于创建灵活、...
反射是PHP的一个强大特性,它允许程序在运行时检查类、接口、方法和属性的信息。在依赖注入的上下文中,反射机制被用来动态地获取类的构造函数或方法的参数信息,以便于创建和注入相应的依赖对象。 首先,我们看一...
泛型是Java SE 5.0引入的新特性,它允许在定义类、接口和方法时使用类型参数,从而提高代码的类型安全性和可读性。泛型的主要优点是可以避免强制类型转换,并在编译时检查类型安全。例如,你可以定义一个泛型类`...
在C#编程中,接口(Interface)是一种定义行为规范的类型,它允许类或结构体遵循特定的约定,实现接口中的所有成员。接口可以包含方法、属性、索引器和事件,但不能包含字段或构造函数。接口有两种实现方式:隐式...
在Java编程中,反射是一种强大的工具,它允许我们在运行时检查和操作类、接口、字段以及方法的信息。这里我们关注的是如何使用反射来向简单的JavaBean对象中设置和获取值,而不必显式地创建这些对象。这个过程涉及到...
6. **数据绑定**:Spring MVC中,表单数据与控制器方法参数之间的绑定也是通过反射完成的。它可以自动将请求参数映射到方法参数上,简化了处理HTTP请求的工作。 7. **事件驱动**:Spring应用上下文支持事件发布和...
总之,通过Java的反射机制,我们可以访问并调用Android系统中的隐藏API,实现蓝牙设备的显式配对和解配对。然而,这种方法并不稳定,可能会因为Android版本更新或安全策略改变而失效。因此,建议开发者关注官方SDK的...
在C#中,我们可以定义泛型类、泛型接口、泛型方法等。例如,`List<T>`就是一个常见的泛型类,其中`T`代表一个未知的数据类型,可以是任何引用类型或值类型。使用泛型可以避免装箱和拆箱操作,提升性能,并确保类型...
在反射中,虚函数可以用于实现动态的方法调用。 5. **静态成员和枚举**:静态成员可以用来存储类的元数据,例如方法名和参数类型。枚举可以用来表示特定的反射操作,如创建实例、调用方法等。 6. **映射表...
3.继承这个接口的类必须实现接口的所有方法,且必须为public实现:当一个类实现接口时,它必须提供接口中所有方法的具体实现。这些实现的方法必须是public的,因为接口中的方法默认就是public的,这符合接口的契约...
反射允许我们在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。以下是一个简化的转换过程: 1. **解析JSON字符串**:首先,我们需要一个JSON字符串。这个字符串可以来源于HTTP...
在 Java 中,泛型的声明通常是在类、接口或方法的名称后面跟上一对尖括号 `<T>`,其中 `T` 是类型参数。例如: ```java class GenericClass<T> { T someField; void someMethod(T t) { // ... } } ``` 这里的 ...