【发布时间】:2012-06-06 20:54:40
【问题描述】:
我收到以下运行时异常:
System.TypeLoadException 未处理
Message=Method 'Specialize' on type [...] 试图隐式覆盖具有较弱类型参数约束的方法。
这个内部函数似乎是问题所在:
let getKey (r: IDictionary<_,_>) =
match r.TryGetValue(keyCol.Name) with
| true, k when not (isNull k) -> Some k
| _ -> None
签名是IDictionary<string,'a> -> 'a option (requires 'a : null)。约束从isNull 传播。
在 ILSpy 中查看,getKey 被编译为 FSharpTypeFunc 的子类型,覆盖 Specialize<T>()。
这是一个错误吗?我可以通过在对isNull 的调用中装箱k 来解决这个问题,这消除了约束。
编辑
这是一个完整的复制品:open System.Collections.Generic
let isNull = function null -> true | _ -> false
type KeyCol = { Name : string }
let test() =
seq {
let keyCol = { Name = "" }
let getKey (r: IDictionary<_,_>) =
match r.TryGetValue(keyCol.Name) with
| true, k when not (isNull k) -> Some k
| _ -> None
getKey (dict ["", box 1])
}
test() |> Seq.length |> printfn "%d"
这是 Visual Studio 2008 中的控制台应用程序,面向 .NET 4.0。奇怪的是,该代码在 FSI 中有效。
这是程序集的 PEVerify 输出:
[令牌 0x02000004] 类型加载失败。
[IL]:错误:[D:\TEST\bin\Debug\TEST.exe : Test+test@10[a]::GenerateNext] [mdToken=0x6000012][offset 0x00000031] 无法解析令牌。
2 验证 D:\TEST\bin\Debug\TEST.exe 的错误
【问题讨论】:
-
听起来这可能是一个错误,但发布完整的重现对您会有所帮助 - 您列出的代码对我来说编译得很好(给定免费标识符的一些任意定义)。
-
不错,看起来确实像个错误!它会随着
let inline而消失吗? -
@kvb:我添加了一个复制品。看起来将其包装在
seq { }块中会导致问题。 -
@toyvo:是的,
inline没有任何区别。 -
我继续发给 fsbugs。