2011-09-07 7 views
6

를 계층 구조 나는 다음과 같은 코드가 있습니다F 번호 차별 조합은

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) 

에서 좋은 번역의 경우 궁금해?

+0

괜찮아요. 당신이 빠진 것을 제외하고는; block_1, block_2 및 block_3 이후 –

+2

실례지만, 'block_3'인 것처럼 보이지만 F # 스 니펫에서는 실행할 수 없습니다 (대수 데이터 유형은 내가 아는 한 "닫습니다"). 왜 그런가요? 또한 번역에서 다형성을 사용해야한다고 생각하는 사람은 나뿐입니까? – delnan

+0

당신은 block_3에 대해 절대적으로 모두 맞습니다. – Hugo

답변

11

F # 구분 된 공용 구조체는 OO 클래스 계층 구조와 매우 유사하므로이 옵션이 가장 좋습니다. 가장 주목할만한 차이점은 유형 선언을 수정하지 않고 차별화 된 공용체에 새 사례를 추가 할 수 없다는 것입니다. 다른 한편으로는, 타입을 가지고 작동하는 새로운 함수를 쉽게 추가 할 수 있습니다 (대략적으로 C#에서 새로운 가상 메소드를 추가하는 것에 해당합니다).

따라서 새로운 상속 된 클래스 (사례)를 추가 할 필요가 없다면이 옵션이 가장 좋습니다. 그렇지 않으면 F # 개체 유형 (또는 시나리오에 따라 다른 옵션)을 사용할 수 있습니다.

코드에 관한 한 가지 더 중요한 점은 새로운 케이스를 추가 할 수 없으므로 F # 컴파일러는 BC에 필요한 케이스 만 알 수 있습니다. 그 결과, block_3는 그냥 쓸 수 있다는 것을 의미하는 실행되지 않을 수 있습니다

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

예이 F 번호가 어쨌든처럼 다소 동일합니다. 이 경우 (부가가치 없음) - F #이 "a"및 일부 태그 (열거)에 대한 클래스로 변환하는 것으로 보입니다. "a"는 단지 B 및 C에 대한 약간의 정적 특성 및 몇 가지 방법이있다의 클래스 타입의 객체는 "a"는 "B"또는 "C"인 경우

Object-Browser of the types

(아래 참조)을 확인하기 위하여 그러나 "_ -> (block_3)"대/소문자는 필요하지 않습니다. 일치 할 수 없기 때문에 (F #은 모든 가능한 경우를 알고 경고합니다).

"else"의 경우 C#에서 예외를 throw하면 더 좋을 것이라고 생각합니다.

+0

음 Tomas가 더 멋지다고 생각합니다.) – Carsten