Domanda

Ho il seguente codice:

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

e mi chiedo se sia una buona traduzione da F #

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

??

È stato utile?

Soluzione

Le unioni discriminate in F # corrispondono abbastanza strettamente alle gerarchie di classi OO, quindi questa è probabilmente l'opzione migliore.La differenza più notevole è che non è possibile aggiungere nuovi casi a un'unione discriminata senza modificare la dichiarazione del tipo.D'altra parte, puoi facilmente aggiungere nuove funzioni che funzionano con il tipo (che corrisponde grosso modo all'aggiunta di nuovi metodi virtuali in C #).

Quindi, se non ti aspetti di aggiungere nuove classi (case) ereditate, questa è l'opzione migliore.Altrimenti, puoi usare i tipi di oggetto F # (o altre opzioni, a seconda dello scenario).

Un altro punto sul codice: poiché non è possibile aggiungere nuovi casi, il compilatore F # sa che gli unici casi di cui hai bisogno sono B e C.Di conseguenza, block_3 non può mai essere eseguito, il che significa che puoi scrivere solo:

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

Altri suggerimenti

sì, questo è più o meno lo stesso di F # comunque. In questo caso (nessun valore aggiunto) - F # sembra tradurlo in classi a per "a" e alcuni tag (enumerazione).La classe per "a" ha solo alcune proprietà statiche per B e C e alcuni metodi per verificare se un oggetto di tipo "a" è "B" o "C" (vedi sotto)

Browser degli oggetti dei tipi

Ma non hai bisogno del caso "_ -> (block_3)", perché questo non può mai essere trovato (F # conosce tutti i casi possibili e ti avviserà).

Penso che sia meglio se lanci un'eccezione in C # per questo caso "else".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top