在我的VS2010解决方案中,C#app项目引用了一个F#库项目。
当从F#lib抛出NullReferenceException
时,调试器无法找到抛出的点异常。它只是说“没有可用的来源”。
我应该更改某些选项还是这是VS2010的限制?
我添加了一些示例代码:
F#project'Library1'
module Module1
type AA() =
let _a = "xx"
member x.a = _a
let aa:AA option = None
let b() =
aa.Value.a // null reference occurs here
C#项目'ConsoleApp1'
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.Out.Write(Module1.b());
Console.In.Read();
}
}
}
答案 0 :(得分:2)
原则上,这应该在不设置任何其他选项的情况下工作。要检查的一些事项:
运行时是否可以找到F#库的PDB文件?
如果PDB文件与DLL位于同一目录中,则应该这样做。您还可以查看“输出”窗口并从组合中选择“调试”以查看应用程序启动时打印的信息 - 您可以在其中查看符号是否已加载。如果您在某个特殊目录中有PDB符号,则可以在工具中指定目录 - >选项 - >调试 - >符号
当您尝试在F#源中设置断点时会发生什么?
它是否表示“未加载符号”(并以灰色显示断点)?它是否显示了可用于查找问题原因的任何其他信息?
答案 1 :(得分:0)
错误不是由任何C#/ F#互操作问题引起的。
当您调用b()
时,它会尝试访问None选项值的值,该值会在运行时抛出空引用异常。
在F#lib中,尝试将let aa:AA option = None
替换为let aa:AA option = Some(AA())
。然后C#代码应打印'xx'。
将F#选项类型暴露给外部世界时,可以允许空选项的空返回值而不是异常。例如:
module Module1
//attribute needed in order to be able to return null from the match statement
[<AllowNullLiteralAttribute>]
type AA() =
let _a = "xx"
member x.a = _a
let aa:AA option = None
let b() = match aa with
| None -> null
| Some value -> value
并在使用此F#库的任何代码中检查null。
请注意AllowNullLiteral
属性。尝试注释掉这个属性,你会发现F#在第一个匹配分支中不会识别null值。