Возможность обрабатывать 's[]
как 't[]
, когда 's :> 't
делает систему типов .NET неработоспособной (и, вероятно, из-за того, что Java делает то же самое). К сожалению, C # следует .NET в разрешении этого.
Поскольку это функция времени выполнения .NET, вы также можете сделать это в F # через бокс и распаковку:
let x : float[][] = Array.init 2 (fun x -> Array.zeroCreate 3)
let x' = (box x) :?> System.Array[]
Это позволяет избежать накладных расходов при отображении каждого элемента, как в решении Рамона.
Чтобы понять, почему это делает систему типов .NET неработоспособной, рассмотрим следующее:
x'.[0] <- upcast [| "test" |] // System.ArrayTypeMismatchException
Несмотря на то, что мы храним значение типа System.Array
в System.Array[]
, мы получаем исключение во время выполнения, поскольку истинный тип базового массива не может поддерживать операцию (x
и x'
только два представления одного и того же массива, и, очевидно, string[]
не может быть сохранен в x
). Эта несостоятельность в системе типов .NET, следовательно, имеет нежелательный побочный эффект: для большинства хранилищ в массивах требуются дополнительные издержки, чтобы гарантировать, что хранимое значение имеет тип, совместимый с базовым массивом. На мой взгляд, хорошо, что F # не позволяет вам делать это напрямую.