Прототипный код в С#:
if(obj1 is ISomeInterface) {
do_something
}
Код в F #, который не компилируется:
match obj1 with
| :? ISomeInterface -> do_something
| _ -> ()
Прототипный код в С#:
if(obj1 is ISomeInterface) {
do_something
}
Код в F #, который не компилируется:
match obj1 with
| :? ISomeInterface -> do_something
| _ -> ()
match box obj1 with
| :? ISomeInterface -> do_something
| _ -> ()
Чтобы добавить объяснения ответов desco и Brian, добавление box
необходимо, если статический тип значения obj1
может не быть ссылочным типом .NET.
Если тип obj1
равен obj
(введите псевдоним для System.Object
), вы можете использовать сопоставление шаблонов без какого-либо бокса, потому что компилятор уже знает, что у вас есть ссылочный тип:
let obj1 : obj = upcast (...)
match obj1 with
| :? ISomeInterface -> (do something)
В случае, если вам нужно box
, когда тип obj1
является типичным параметром типа. В этом случае ваша функция может быть вызвана как с типами значений, так и с типами ссылок. Добавление box
гарантирует, что вы выполняете тест типа для ссылочного типа (а не по типу значения, что невозможно).
match box obj1 with ...
Я думаю (набрав с моего телефона:)
Пока match box obj1 with ...
выполняет задание, существует команда box
IL, испускаемая компилятором F #. Инструкция Box опасна, поскольку в некоторых случаях она медленная.
Если вы знаете, что obj1 уже является ссылочным типом, рекомендуется использовать более быстрый подход :> obj
:
match obj1 :> obj with
| :? ISomeInterface -> (do something)
obj1 :> obj
эквивалентно операции литья типа С# (object)obj1
. Кроме того, компилятор F # оптимизирует эту чрезмерную операцию отбрасывания, когда проект построен в конфигурации Release, поэтому вы получаете самый быстрый код в этом случае.