- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有以下 C# 类
public class BadClass
{
public BadClass(int? bad = 1)
{
}
}
public class GoodClass
{
public GoodClass(int? good = null)
{
}
}
如您所见,它们都有可选的可空参数作为其构造函数的一部分,唯一的区别是 BadClass 将参数默认设置为 null 以外的其他值。
如果我尝试在 F# 中创建这些类的实例,这就是我得到的结果:
这很好用:
let g = GoodClass()
这会抛出 NullReferenceException:
let b = BadClass()
这会抛出一个 AccessViolationException
let asyncB = async { return BadClass() } |> Async.RunSynchronously
知道这是为什么吗?
编辑
使用 ILSpy 反编译它,这是 F# 的输出
C# 类位于名为 InteopTest [sic] 的程序集中
ILSpy 到 C#
GoodClass g = new GoodClass(null);
BadClass b = new BadClass(1);
FSharpAsyncBuilder defaultAsyncBuilder = ExtraTopLevelOperators.DefaultAsyncBuilder;
FSharpAsync<BadClass> fSharpAsync = defaultAsyncBuilder.Delay<BadClass>(new Program.asyncB@10(defaultAsyncBuilder));
FSharpAsync<BadClass> computation = fSharpAsync;
BadClass asyncB = FSharpAsync.RunSynchronously<BadClass>(computation, null, null);
FSharpFunc<string[], Unit> fSharpFunc = ExtraTopLevelOperators.PrintFormatLine<FSharpFunc<string[], Unit>>(new PrintfFormat<FSharpFunc<string[], Unit>, TextWriter, Unit, Unit, string[]>("%A"));
fSharpFunc.Invoke(argv);
return 0;
这就是IL
.method public static
int32 main (
string[] argv
) cil managed
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2050
// Code size 92 (0x5c)
.maxstack 5
.entrypoint
.locals init (
[0] class [InteopTest]InteopTest.GoodClass g,
[1] valuetype [mscorlib]System.Nullable`1<int32>,
[2] class [InteopTest]InteopTest.BadClass b,
[3] class [InteopTest]InteopTest.BadClass asyncB,
[4] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [InteopTest]InteopTest.BadClass>,
[5] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@,
[6] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [InteopTest]InteopTest.BadClass>,
[7] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string[], class [FSharp.Core]Microsoft.FSharp.Core.Unit>,
[8] string[]
)
IL_0000: nop
IL_0001: ldloca.s 1
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0009: ldloc.1
IL_000a: newobj instance void [InteopTest]InteopTest.GoodClass::.ctor(valuetype [mscorlib]System.Nullable`1<int32>)
IL_000f: stloc.0
IL_0010: ldc.i4.1
IL_0011: newobj instance void [InteopTest]InteopTest.BadClass::.ctor(valuetype [mscorlib]System.Nullable`1<int32>)
IL_0016: stloc.2
IL_0017: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::get_DefaultAsyncBuilder()
IL_001c: stloc.s builder@
IL_001e: ldloc.s builder@
IL_0020: ldloc.s builder@
IL_0022: newobj instance void Program/asyncB@10::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder)
IL_0027: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<!!0> [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay<class [InteopTest]InteopTest.BadClass>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<!!0>>)
IL_002c: stloc.s 4
IL_002e: ldloc.s 4
IL_0030: stloc.s 6
IL_0032: ldloc.s 6
IL_0034: ldnull
IL_0035: ldnull
IL_0036: call !!0 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync::RunSynchronously<class [InteopTest]InteopTest.BadClass>(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<!!0>, class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<int32>, class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1<valuetype [mscorlib]System.Threading.CancellationToken>)
IL_003b: stloc.3
IL_003c: ldstr "%A"
IL_0041: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string[], class [FSharp.Core]Microsoft.FSharp.Core.Unit>, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit, string[]>::.ctor(string)
IL_0046: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string[], class [FSharp.Core]Microsoft.FSharp.Core.Unit>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0, class [mscorlib]System.IO.TextWriter, class [FSharp.Core]Microsoft.FSharp.Core.Unit, class [FSharp.Core]Microsoft.FSharp.Core.Unit>)
IL_004b: stloc.s 7
IL_004d: ldarg.0
IL_004e: stloc.s 8
IL_0050: ldloc.s 7
IL_0052: ldloc.s 8
IL_0054: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<string[], class [FSharp.Core]Microsoft.FSharp.Core.Unit>::Invoke(!0)
IL_0059: pop
IL_005a: ldc.i4.0
IL_005b: ret
} // end of method Program::main
最佳答案
对我来说,这看起来像是 F# 编译器中的错误。如果您编写一些额外的 C#:
public class OtherClass
{
private static BadClass _bc = new BadClass();
}
然后查看 IL,您会看到:
// push 1 on the stack
IL_0000: ldc.i4.1
// call Nullable<int32> constructor, leaving object on stack
IL_0001: newobj instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
// call BadClass constructor with int?
IL_0006: newobj instance void Nullabool.BadClass::.ctor(valuetype [mscorlib]System.Nullable`1<int32>)
// store in _bc
IL_000b: stsfld class Nullabool.BadClass Nullabool.OtherClass::_bc
这清楚地用 1 实例化了 Nullable`1。
而 b 的 F# 代码最终是这样的:
// push a 1 on the stack
IL_0016: ldc.i4.1
// call BadClass constructor with 1 - this fails IL verification
IL_0017: newobj instance void [Nullabool]Nullabool.BadClass::.ctor(valuetype [mscorlib]System.Nullable`1<int32>)
它在堆栈上留下一个 int
而不是 int?
。当我尝试运行此代码时,由于类型不匹配,我收到 IL 验证错误。
关于c# - F# 与 C# 类互操作,该类具有一个可选的可空参数设置为除 null 之外的任何值会导致 NullReferenceException/AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20980929/
简而言之:我想从可变参数模板参数中提取各种选项,但不仅通过标签而且通过那些参数的索引,这些参数是未知的 标签。我喜欢 boost 中的方法(例如 heap 或 lockfree 策略),但想让它与 S
我可以对单元格中的 excel IF 语句提供一些帮助吗? 它在做什么? 对“BaselineAmount”进行了哪些评估? =IF(BaselineAmount, (Variance/Baselin
我正在使用以下方法: public async Task Save(Foo foo,out int param) { ....... MySqlParameter prmparamID
我正在使用 CodeGear RAD Studio IDE。 为了使用命令行参数测试我的应用程序,我多次使用了“运行 -> 参数”菜单中的“参数”字段。 但是每次我给它提供一个新值时,它都无法从“下拉
我已经为信用卡类编写了一些代码,粘贴在下面。我有一个接受上述变量的构造函数,并且正在研究一些方法将这些变量格式化为字符串,以便最终输出将类似于 号码:1234 5678 9012 3456 截止日期:
MySql IN 参数 - 在存储过程中使用时,VarChar IN 参数 val 是否需要单引号? 我已经像平常一样创建了经典 ASP 代码,但我没有更新该列。 我需要引用 VarChar 参数吗?
给出了下面的开始,但似乎不知道如何完成它。本质上,如果我调用 myTest([one, Two, Three], 2); 它应该返回元素 third。必须使用for循环来找到我的解决方案。 funct
将 1113355579999 作为参数传递时,该值在函数内部变为 959050335。 调用(main.c): printf("%d\n", FindCommonDigit(111335557999
这个问题在这里已经有了答案: Is Java "pass-by-reference" or "pass-by-value"? (92 个回答) 关闭9年前。 public class StackOve
我真的很困惑,当像 1 == scanf("%lg", &entry) 交换为 scanf("%lg", &entry) == 1 没有区别。我的实验书上说的是前者,而我觉得后者是可以理解的。 1 =
我正在尝试使用调用 SetupDiGetDeviceRegistryProperty 的函数使用德尔福 7。该调用来自示例函数 SetupEnumAvailableComPorts .它看起来像这样:
我需要在现有项目上实现一些事件的显示。我无法更改数据库结构。 在我的 Controller 中,我(从 ajax 请求)传递了一个时间戳,并且我需要显示之前的 8 个事件。因此,如果时间戳是(转换后)
rails 新手。按照多态关联的教程,我遇到了这个以在create 和destroy 中设置@client。 @client = Client.find(params[:client_id] || p
通过将 VM 参数设置为 -Xmx1024m,我能够通过 Eclipse 运行 Java 程序-Xms256M。现在我想通过 Windows 中的 .bat 文件运行相同的 Java 程序 (jar)
我有一个 Delphi DLL,它在被 Delphi 应用程序调用时工作并导出声明为的方法: Procedure ProduceOutput(request,inputs:widestring; va
浏览完文档和示例后,我还没有弄清楚 schema.yaml 文件中的参数到底用在哪里。 在此处使用 AWS 代码示例:https://github.com/aws-samples/aws-proton
程序参数: procedure get_user_profile ( i_attuid in ras_user.attuid%type, i_data_group in data_g
我有一个字符串作为参数传递给我的存储过程。 dim AgentString as String = " 'test1', 'test2', 'test3' " 我想在 IN 中使用该参数声明。 AND
这个问题已经有答案了: When should I use "this" in a class? (17 个回答) 已关闭 6 年前。 我运行了一些java代码,我看到了一些我不太明白的东西。为什么下
我输入 scroll(0,10,200,10);但是当它运行时,它会传递字符串“xxpos”或“yypos”,我确实在没有撇号的情况下尝试过,但它就是行不通。 scroll = function(xp
我是一名优秀的程序员,十分优秀!