C#用Call代替CallVirt之后的测试用例
2024-08-31 20:36:47
一. C# 原始代码和直接结果
测试 C# 代码:
class Program
{
static void Main(string[] args)
{
A c1 = new C();
c1.Foo(); C c2 = new C();
c2.Foo(); Console.ReadKey();
}
}
class A
{
public virtual void Foo()
{
Console.WriteLine("Call on A.Foo()");
}
}
class B : A
{
public override void Foo()
{
Console.WriteLine("Call on B.Foo()");
}
}
class C : B
{
public new void Foo()
{
Console.WriteLine("Call on C.Foo()");
}
}
运行结果:
二. IL程序编译的IL代码执行结果
IL 代码:
.assembly extern mscorlib
{
auto
}
.assembly MyTest{}
.module MyTest.exe .class public A
{
.method public specialname void .ctor()
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
} .method public newslot virtual void Foo()
{
ldstr "Call on A.Foo()"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
}
.class public B extends A
{
.method public specialname void .ctor()
{
ldarg.0
call instance void A::.ctor()
ret
} .method public virtual void Foo()
{
ldstr "Call on B.Foo()"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
}
.class public C extends B
{
.method public specialname void .ctor()
{
ldarg.0
call instance void B::.ctor()
ret
} .method public void Foo()
{
ldstr "Call on C.Foo()"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
}
.method public static void Main()
{
.entrypoint
.locals (class A v_0,class C v_1)
newobj instance void C::.ctor()
stloc.0
ldloc.0
callvirt instance void A::Foo()
newobj instance void C::.ctor()
stloc.1
ldloc.1
callvirt instance void C::Foo()
call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
pop
ret
}
运行结果:
三. 用 Call 代替 CallVirt 的 IL
IL 代码:
.assembly extern mscorlib
{
auto
}
.assembly MyTest{}
.module MyTest.exe .class public A
{
.method public specialname void .ctor()
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
} .method public newslot virtual void Foo()
{
ldstr "Call on A.Foo()"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
}
.class public B extends A
{
.method public specialname void .ctor()
{
ldarg.0
call instance void A::.ctor()
ret
} .method public virtual void Foo()
{
ldstr "Call on B.Foo()"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
}
.class public C extends B
{
.method public specialname void .ctor()
{
ldarg.0
call instance void B::.ctor()
ret
} .method public void Foo()
{
ldstr "Call on C.Foo()"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
}
.method public static void Main()
{
.entrypoint
.locals (class A v_0,class C v_1)
newobj instance void C::.ctor()
stloc.0
ldloc.0
call instance void A::Foo()
newobj instance void C::.ctor()
stloc.1
ldloc.1
call instance void C::Foo()
call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
pop
ret
}
运行结果:
四. 结论
如果使用 Call 的话,它会简单粗暴的指针调用代码,即 A 中的 Foo 方法的代码进行执行。
最新文章
- excel转json工具的制作(C#语言)
- centos6.5编译安装lamp开发环境
- MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
- 关于ImageLoader的详细介绍
- 使用pip安装python插件的时候出现Microsoft Visual C++ 9.0缺失错误
- 浅谈html语义化标签,Html5新增语义化标签
- cocos2dx libjson
- 【暴力模拟】UVA 1594 - Ducci Sequence
- tpl demo
- Expanding Rods(二分)
- python运维开发之第九天
- 字体在Android View中的输出 drawText
- php 添加 redis 扩展模块
- 迪杰斯特拉(Dijkstra)算法
- 基于visual Studio2013解决面试题之0405和最大的子矩阵
- Android Fragment 开发(一)
- Java对象的访问定位
- Git Bash+EGit在项目中配合使用最常用方法总结(根据场景使用)
- CSS Modules 与 scoped 的不一样
- silverlight用Encoding.UTF8读取shape文件的中文属性值 出现乱码
热门文章
- JS-正则表达式解析
- 如何设计APP版本号?
- Go-接口(作用类似python类中的多态)
- Set a One-to-Many Relationship设置一对多关系 (EF)
- 使用NodeJS模块-第三方提供的模块(什么是npm)
- Cobalt Strike系列教程第二章:Beacon详解
- 百度地图API----搜索地址,获取该点的位置坐标并转换成WebMercator
- Java反射02 : Class对象获取的三种方式和通过反射实例化对象的两种方式
- 使用User-Agent防止HttpClient发送http请求时403 Forbidden和安全拦截
- Hive静态分区和动态分区,对应Mysql中的元数据信息