- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试为属性生成动态代理。
生成的代理源 self 们要代理的类型。当代理需要访问其派生类型的(虚拟)属性时,不能使用 OpCodes.Callvirt
- 它会导致无限递归。因此我们需要调用OpCodes.Call
。我注意到如果我有:
public class MyParent
{
protected string _name;
protected string _color;
public virtual string Name
{
get { return _name; }
set { _name = value; }
}
public virtual string Color
{
get { return _color; }
set { _color = value; }
}
}
public class MyChild : MyParent
{
public override string Name {
get { return "42"; }
set { _name = value; }
}
}
当我在从 MyChild
派生的代理对象上发出 OpCodes.Call
以调用 get_Color
时,它会被正确调用,即使从技术上讲这个方法未在 MyChild
上实现。
我打算编写一些代码,将类型层次结构向下遍历到 MyParent
,其中可以找到 get_Color
实现,并将该类型方法用于 OpCodes.Call
,但似乎没有必要:
var thisTypeMethod = property.GetGetMethod();
// I know that the next line technically is not correct because of non-virtual methods
// and also *new* overrides. Assume I'm doing it correctly, not by property.Name
// but by repeatedly calling MethodInfo.GetBaseDefinition()
var declaringTypeMethod = property.DeclaringType.GetProperty(property.Name).GetGetMethod();
然后
var proxyMethod = new DynamicMethod(thisTypeMethod.Name,thisTypeMethod.ReturnType, new Type[]{type},type,true);
var il = proxyMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Tailcall);
il.Emit(OpCodes.Call, thisTypeMethod);
il.Emit(OpCodes.Ret);
不使用 declaringTypeMethod 而是使用 thisTypeMethod 是否安全?
最佳答案
您通常不需要声明类型的实现。
大概您想要做的事情与 base
关键字对 C# 编译器所做的事情相同。 C# 编译器实际上查找最派生的父实现并直接调用它,但您所做的也是完全合法的。
如果基类在另一个程序集中,它们会有不同的行为,并且该程序集会在代码生成运行后重新编译并添加新的覆盖。有关更多详细信息,请参阅 Eric Lippert(C# 编译器主要开发人员之一)的这篇博客文章,其中解决了这个确切场景:
这个问题说明了针对当前方法的 OpCodes.Call
与具有实际实现的最派生父级之间的行为差异:
重申一下,您不想使用 DeclaringType
中的实现,这通常不是上述两个合理选择中的任何一个。
关于c# - 在虚拟方法上使用 OpCodes.Call 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30972209/
我有一个递归函数 emit : Map -> exp -> unit哪里il : ILGenerator对函数来说是全局的,并且 exp是一个判别联合,表示带有大小写 InstanceCall of
我正在使用 ASM 框架进行 java 字节码操作。 ASM中出现两次的一些操作码助记符,它们以“H_”为前缀: Opcodes.H_GETFIELD vs. Opcodes.GETF
谁能告诉我以下段错误究竟意味着什么? Unhandled dwarf expression opcode 0x93 它在solaris 10 i386上。 任何建议表示赞赏。 最佳答案 如果您的 GD
在构建芯片 8 仿真器时,我遇到了芯片 8 信息的 2 个主要来源似乎不同的问题,这对整个芯片 8 解释器有影响。 一方面,我们有 wikipedia , 在操作码 FX65 下告诉我们 “用从地址
在intel software developers manual volumen 2A chapter 2.1.2说 Two-byte opcode formats for general-purp
.NET Framework 4.0 向 Reflection API 引入了多项内容,这些内容对我的工作从极其有用到至关重要。其中包括 Assembly、Module、MethodBody 和 Lo
我正在使用 Kony Studio 开发应用程序。我已经使用 Eclipse 完成了登录验证,以编写用于创建 Web 服务以连接到 oracle10g 数据库的代码。但是在前端,当我尝试将前端连接到
当您在堆栈顶部引用 (B) 的实例时,是否有必要发出 OpCode.CastClass(typeof(A)),其中 B 是派生自 A 的类,当准备调用方法时类型 A 的参数? 添加: interfac
如果我有一个 lua 脚本,比如 print("Hello, world!") 我如何获得与之等效的指令或操作码? (用于 luaV_execute) 最佳答案 您几乎不需要对 Lua 的解释器做一个
我们的计算机体系结构教授给了我们一个示例程序,要求输入密码。任务是在比较输入的密码并决定是否正确后更改跳转操作码。我编写了一个程序,可以更改给定二进制文件中特定位置的任何字节。 这是密码程序的代码:
我有一个包含以下代码的汇编程序。 这段代码对于英特尔处理器来说编译得很好。但是,当我使用 PPC(交叉)编译器时,我收到一个错误,提示无法识别操作码。我试图找出是否有 PPC 架构的等效操作码。 .f
这可能是一个非常奇怪的问题,但我一直在小人电脑上做一些工作,这让我有点恼火,不仅没有操作代码 4,而且互联网上也绝对没有关于为什么。 操作码从 0 到 9 但跳过 4。从来没有任何以 4 开头的三位数
我正在阅读Go源代码,就像读过一样,当我阅读fastrand()函数时(对于我的机器,该函数位于asm_amd64.s文件中),我遇到了以下片段: XORL $0x88888eef, D
我设置了一个简单的 Geth (v1.10.2-stable-97d11b01) 专用网络(下面的 genesis.json 配置)。我编译并部署了这个简单的测试合约(solidity版本:0.8.4
我对此很陌生。我试图以清晰的方式理解上述术语之间的区别,但是,我仍然感到困惑。这是我发现的: 在计算机汇编语言中,助记符是操作的缩写。它被输入到每个汇编程序指令的操作码字段中。例如 AND AC,37
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我正在尝试为属性生成动态代理。 生成的代理源 self 们要代理的类型。当代理需要访问其派生类型的(虚拟)属性时,不能使用 OpCodes.Callvirt - 它会导致无限递归。因此我们需要调用Op
有什么办法可以改变OpCodes.Ret跳转到的地址吗? IL 中的方法可以更改 C# 使用的调用堆栈吗? 据我所知,在 C++ 中,您可以访问堆栈上的值并更改返回地址等。在 IL 中,除了“Inva
我已经在我的 linuxbox 上安装了 Zend OpCache。我使用以下命令安装扩展: sudo pecl install zendopcache-7.0.2 现在,无需修改我的 php.ini
许多框架利用 spl_autoload_register() 来动态加载类(即 Controller 和模型)。有几篇关于自动加载和操作码缓存问题的帖子。特别是一篇帖子有@cletus 的回复,其中引
我是一名优秀的程序员,十分优秀!