Как проверить в F # реализует ли объект интерфейс - PullRequest
10 голосов
/ 20 марта 2011

Прототип кода в C #:

if(obj1 is ISomeInterface) {
   do_something
}

Код в F #, который не компилируется:

match obj1 with 
| :? ISomeInterface -> do_something
| _ -> ()

Ответы [ 4 ]

14 голосов
/ 20 марта 2011

Чтобы добавить пояснения к ответам Деско и Брайана - добавление box необходимо, когда статический тип значения obj1 не обязательно должен быть ссылочным типом .NET.

Если типиз obj1 равно obj (введите псевдоним для System.Object), тогда вы можете использовать сопоставление с образцом без каких-либо ограничений, поскольку компилятор уже знает, что у вас есть ссылочный тип:

let obj1 : obj = upcast (...)
match obj1 with 
| :? ISomeInterface -> (do something)

Случай, когда выbox нужен, когда тип obj1 является параметром универсального типа.В этом случае ваша функция может вызываться как с типами значений, так и с ссылочными типами.Добавление box гарантирует, что вы выполняете проверку типа для ссылочного типа (а не для типа значения, что невозможно).

13 голосов
/ 20 марта 2011
match box obj1 with 
| :? ISomeInterface -> do_something
| _ -> ()
5 голосов
/ 25 декабря 2014

Пока match box obj1 with ... выполняет свою работу, существует инструкция box IL, генерируемая компилятором F #. Ящик с инструкциями опасен, потому что в некоторых случаях он медленный.

Если вы знаете, что obj1 уже является ссылочным типом , то рекомендуется более быстрый :> obj подход:

match obj1 :> obj with
    | :? ISomeInterface -> (do something)

obj1 :> obj эквивалентно операции приведения типа C # (object)obj1. Более того, компилятор F # оптимизирует эту чрезмерную операцию приведения при построении проекта в конфигурации Release, поэтому в этом случае вы получите самый быстрый код.

3 голосов
/ 20 марта 2011
match box obj1 with ...

Я думаю (набрав со своего телефона:)

...