2010-03-05 3 views

답변

33

람다 식에서 멤버를 자주 호출해야하기 때문에 F #에서는 protected 수정자가 상당히 문제가 될 수 있습니다. 그러나 그렇게하면 더 이상 클래스 내에서 메소드에 액세스 할 수 없습니다. 또한 C#으로 선언 된 보호 된 멤버를 사용할 때 혼란을 야기합니다 (예 : this SO question 참조). 당신이 protected 멤버를 선언 할 수 있다면, 다음 코드는 놀라운 일이 될 수있다 :

type Base() = 
    protected member x.Test(a) = a > 10 

type Inherited() = 
    inherit Base() 
    member x.Filter(list) = 
    list |> List.filter (fun a -> x.Test(a)) 

이 코드는 작동하지 않을 것입니다, 당신의 현재 인스턴스와 다른 객체 인 (람다 함수에서 Test를 호출하고 있기 때문에 Test) 코드가 작동하지 않습니다. 이것이 F #에서 protected 수식어를 지원하지 않는 주된 이유라고 생각합니다.

F #에서는 일반적으로 C#보다 구현 상속 (즉, 기본 클래스에서 상속)을 사용하므로 훨씬 자주 protected이 필요하지 않습니다. 대신 일반적으로 인터페이스 (객체 지향 F # 코드에서)와 고차 함수 (기능 코드에서)를 사용하는 것이 좋습니다. 그러나 구현 상속을 피하는 것 이외에 일반적으로 protected의 필요성을 피하는 방법을 말하는 것은 어렵습니다. 귀하의 질문에 동기를 부여하는 구체적인 예가 있습니까?

+26

이것은 사실이지만 컴파일러의 구현 아티팩트입니다. F #과 같은 .NET 언어가 클로저를 수용하고 의도 한 의미를 갖는 중첩 클래스를 생성 할 수 없다는 근본적인 이유는 없습니다. – kvb

+0

좋은 설명. F # 컴파일러가 lambdas 및 기타 기능적 구성을 지원하기 위해 만드는 객체를 잊어 버리는 것은 쉽습니다. 나는 C#에서 자주 사용되는 ORM을 작성하고있다. 그것은 공급자 모델의 무언가를 사용합니다. SqlRepository, OracleRepository 등으로 확장 될 수있는 추상 Repository 클래스가 있습니다. 테이블에 대한 스키마 정보를로드하는 보호 된 메소드가 필요했습니다. 이렇게하는 더 좋은 방법에 대한 아이디어가 있습니까? – Daniel

+0

@kvb - 나는 똑같은 생각. 컴파일 된 멤버가 파생 클래스의 람다에서 액세스되는 경우 컴파일러에서 확인할 수있는 방법이 있습니까? – Daniel

7

F #이 데이터 모델링의 더 나은 방법을 가능하게하는지 여부에 따라, 서명 파일은 C#에서 internal보다 미세한 가시성 결정을 허용합니다. 이는 종종 매우 좋습니다. Brian의 코멘트 here 좀 더 자세한 설명을 참조하십시오. 이것은 protected에 대한 지원과 무관합니다.

+0

링크가 죽은 것처럼 보입니다. – Maslow

+0

@Maslow - 이것을 지적 해 주셔서 감사합니다; 내가 원래 게시물의 거울이라고 생각하는 링크를 업데이트했습니다. – kvb

관련 문제