F # дискриминационные объединения и иерархии классов C # - PullRequest
7 голосов
/ 07 сентября 2011

У меня есть следующий код:

public abstract class A ...
public class B : A ...
public class C : A ...

void my_fct(A x) {
  if (x is B) { block_1 }
  else if (x is C) { block_2 }
  else { block_3 }
}

, и мне интересно, хороший ли это перевод с F #

type a = B | C
let my_fct x =
  match x with
  | B -> ( block_1 )
  | C -> ( block_2 )
  | _ -> ( block_3 )

??

Ответы [ 2 ]

12 голосов
/ 07 сентября 2011

F # различимые союзы достаточно близко соответствуют иерархиям классов OO, так что это, вероятно, лучший вариант. Самым заметным отличием является то, что вы не можете добавлять новые случаи в различаемое объединение без изменения объявления типа. С другой стороны, вы можете легко добавлять новые функции, которые работают с типом (что примерно соответствует добавлению новых виртуальных методов в C #).

Итак, если вы не ожидаете добавления новых унаследованных классов (падежей), тогда это лучший вариант. В противном случае вы можете использовать типы объектов F # (или другие параметры, в зависимости от сценария).

Еще один момент, касающийся вашего кода - поскольку вы не можете добавлять новые случаи, компилятор F # знает, что вам нужны только случаи для B и C. В результате, block_3 никогда не может быть выполнен, что означает, что вы можете написать просто:

let my_fct x = 
  match x with 
  | B -> ( block_1 ) 
  | C -> ( block_2 ) 
7 голосов
/ 07 сентября 2011

Да, это более или менее так же, как F # в любом случае.В этом случае (значения не добавляются) - F #, кажется, переводит это в класс для «a» и некоторых тегов (перечисление).Класс "a" просто имеет некоторые статические свойства для B и C и некоторые методы для проверки, является ли объект типа "a" "B" или "C" (см. Ниже)

Object-Browser of the types

Но вам не нужен случай "_ -> (block_3)", потому что это никогда не может быть сопоставлено (F # знает все возможные случаи и предупредит вас).

Я думаюЛучше, если вы выбросите исключение в C # для этого «другого» случая.

...