Pregunta

Tengo el siguiente código:

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 }
}

y me pregunto si es una buena traducción de F#

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

??

¿Fue útil?

Solución

Las uniones discriminadas de F# se corresponden bastante estrechamente con las jerarquías de clases de OO, por lo que esta es probablemente la mejor opción.La diferencia más notable es que no se pueden agregar nuevos casos a una unión discriminada sin modificar la declaración de tipo.Por otro lado, puede agregar fácilmente nuevas funciones que funcionen con el tipo (lo que corresponde aproximadamente a agregar nuevos métodos virtuales en C#).

Entonces, si no espera agregar nuevas clases heredadas (casos), esta es la mejor opción.De lo contrario, puede usar tipos de objetos de F# (u otras opciones, según el escenario).

Un punto más con respecto a su código: dado que no puede agregar nuevos casos, el compilador de F# sabe que los únicos casos que necesita son para B y C.Como resultado, el block_3 nunca se puede ejecutar, lo que significa que puedes escribir simplemente:

let my_fct x = 
  match x with 
  | B -> ( block_1 ) 
  | C -> ( block_2 ) 

Otros consejos

sí, esto es más o menos lo mismo que hace F # de todos modos. En este caso (sin valores agregados) - F # parece traducir esto en clases para "a" y algunas etiquetas (enumeración).La clase para "a" solo tiene algunas propiedades estáticas para B y C, y algunos métodos para verificar si un objeto de tipo "a" es "B" o "C" (ver más abajo)

Object-Browser de los tipos

Pero no necesitas el caso "_ -> (block_3)", porque esto nunca puede coincidir (F # conoce todos los casos posibles y te advertirá).

Creo que es mejor si lanza una excepción en C # para este caso "más".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top