2016-09-10 4 views
2

string에 표시된 이름을 사용하여 형식 특성에 액세스 할 수있는 방법이 있습니까? 의 라인을 따라 뭔가 : 나는 동적으로 xml 기반의지도에 따라 유형을 액세스 할f # 형식 특성 액세스

type B = {FirstName:string; LastName:string} 
let b = { FirstName="Bob"; LastName="Smith" } 
b.``"FirstName"`` 

이유 존재.

+2

리플렉션을 사용할 수는 있지만 확실한 유형 보호가 손실 될 수 있습니다. 왜냐하면 컴파일러는 형식이 무엇인지 모를 때 유형이 올바른지 확인할 수 없기 때문입니다. –

답변

4

이것은 리플렉션을 통해 할 수 있습니다. 일반 .NET 리플렉션 API 외에도 F #에는 레코드와 같은 기본 F # 유형을 구성하고 분해하기위한 몇 가지 유틸리티 함수를 제공하는 작은 리플렉션 라이브러리 Microsoft.FSharp.Reflection이 함께 제공됩니다.

FSharpType.GetRecordFields(typeof<B>) 

는 그런 다음 값의 배열에 기록을 분해 할 수와 같은 기록에 다시 넣어 :

당신이 사용하는 모든 레코드 필드의 PropertyInfos를 얻을 수

let fields = FSharpValue.GetRecordFields(b) 
let b' = FSharpValue.MakeRecord(typeof<B>, fields) :?> B 

그 위에 자신 만의 퍼시스턴스 라이브러리를 만들 수도 있지만, 이것은 대부분 해결 된 문제입니다. 나는 Json.NET이 레코드를 직렬화하는 것을 처리해야한다고 생각한다. 물론 xml도 마찬가지다.

F #은 형식 공급자 형태로 별개의 대안을 제공합니다. xml이 유형을 파악하는 데 "특히"xml을 통해 통신하는 외부 소스에 액세스하는 경우 특히 그렇습니다. FSharp.Data and XmlProvider을 살펴볼 수 있습니다. 그들은 당신의 예제에서 당신이하는 것과 매우 비슷한 느낌을줍니다. 타입 프로 바이더를 xml 샘플로 가리키고 컴파일하는 동안 xml의 구조에 해당하는 타입을 생성합니다. 따라서 정적으로 형식화 된 방식으로 XML 노드 이름을 F # 코드의 일반 필드 이름으로 사용할 수 있습니다.

유형 공급자는 유형 정의를 선언하고 업데이트해야하는 번거 로움을 줄여주기 때문에 스크립팅 및 탐색 프로그래밍에 적합합니다. 그러나보다 오래가는 응용 프로그램을 만들 때 명시 적으로 정의 된 유형을 표현으로 사용하는 것이 바람직 할 수 있습니다.

+0

완벽한! 의견과 설명 모두에 감사드립니다. –