gpt4 book ai didi

reflection - 你如何发射到具有 'params' 构造函数的类?

转载 作者:行者123 更新时间:2023-12-02 22:09:54 24 4
gpt4 key购买 nike

这是我的 Package 类的定义:

type Package ([<ParamArray>] info : Object[]) =
do
info |> Array.iter (Console.WriteLine)

member this.Count = info.Length

这是 IL,我正在尝试:

let ilGen = methodbuild.GetILGenerator()

ilGen.Emit(OpCodes.Ldstr, "This is 1")
ilGen.Emit(OpCodes.Ldstr, "Two")
ilGen.Emit(OpCodes.Ldstr, "Three")
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object[]>|]))
ilGen.Emit(OpCodes.Ret)

但这似乎行不通。我试过:

ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<String>; typeof<String>; typeof<String>|]))

以及:

ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object>; typeof<Object>; typeof<Object>|]))

但它只是在 mock 我。我做错了什么?

最佳答案

[<ParamArray>]属性向编译器指示方法接受可变数量的参数。但是,CLR 并不真正支持 varargs方法——它只是 C#/VB.NET/F# 编译器提供的语法糖。

现在,如果你拿走 [<ParamArray>] ,你还剩下什么?

(info : Object[])

这是您要调用的构造函数的签名。

因此,您需要使用 newarrstelem操作码来创建一个数组,将值存储到其中,然后使用该数组作为参数调用构造函数。这应该做你想做的(虽然我还没有测试过):

let ilGen = methodbuild.GetILGenerator()

// Create the array
ilGen.Emit(OpCodes.Ldc_I4_3)
ilGen.Emit(OpCodes.Newarr, typeof<obj>)

// Store the first array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_0)
ilGen.Emit(OpCodes.Ldstr, "This is 1")
ilGen.Emit(OpCodes.Stelem_Ref)

// Store the second array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_1)
ilGen.Emit(OpCodes.Ldstr, "Two")
ilGen.Emit(OpCodes.Stelem_Ref)

// Store the third array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_2)
ilGen.Emit(OpCodes.Ldstr, "Three")
ilGen.Emit(OpCodes.Stelem_Ref)

// Call the constructor
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object[]>|]))
ilGen.Emit(OpCodes.Ret)

注意:在此代码中,我使用了 dup OpCode 以避免在存储元素值时创建局部变量来保存数组引用。这是唯一可行的,因为这段代码相当简单——如果您想构建更复杂的东西,我强烈建议您创建一个局部变量来保存数组引用。

关于reflection - 你如何发射到具有 'params' 构造函数的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15513711/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com