문제

F# Interactive는 Winform 또는 WPF 창을 실행할 수 있으므로 강력한 개발 도구입니다. 그리고 거기에서 임의 코드를 호출하십시오.

이것은 '시도 전 코드'접근 방식을위한 방법을 제공합니다.

매우 종종 나는 '경계를 깨고'명시 적으로

  • 개인/보호 방법을 호출합니다
  • 개인 필드 및 속성에 대한 액세스/변경

이것을 달성하기위한 해결 방법이 있습니까?

도움이 되었습니까?

해결책

FSI는 이에 대한 특별한 지원을 제공하지 않지만 반사를 사용하여 원하는 작업을 수행 할 수 있습니다.

open System.Reflection
let field = typeof<MyType>.GetField("fieldName", BindingFlags.NonPublic ||| BindingFlags.Instance)
field.SetValue(myInstance, newVal)

더 쉽게 이동하여 방법이나 연산자를 정의하여 더 쉽게 만들 수 있습니다. 예를 들어 F#의 동적 할당 연산자를 설정하여 개인 필드에 할당 할 수 있습니다.

let (?<-) o s v = 
  let field = (o.GetType()).GetField(s, BindingFlags.NonPublic ||| BindingFlags.Instance)
  field.SetValue(o,v)

myInstance?fieldName <- newVal (* Note: no quotes around fieldName here *)

다음은 공공 또는 개인 분야, 속성 또는 방법을 해결하기위한 조단 코드입니다. 이것이 실패하는 방법에는 여러 가지가 있습니다 (특히 과부하 된 방법에서 사용하려고 시도하면 작동하지 않습니다).

open System
open System.Reflection
open Microsoft.FSharp.Reflection

type DynamicHelper =  
  static member MkMethod<'t,'u> (mi:MethodInfo) o : 't -> 'u=
    let typ = typeof<'t>
    fun t -> 
      let args = 
        if (typ = typeof<unit>) then [||]
        else
          if not (FSharpType.IsTuple typ) then [| box t |]
          else
            FSharpValue.GetTupleFields t
      mi.Invoke(o, args) :?> 'u

let (?) (o:'a) s : 'b =
  let ty = o.GetType()
  let field = ty.GetField(s, BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic)
  if field <> null then field.GetValue(o) :?> 'b
  else
    let prop = ty.GetProperty(s, BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic)
    if prop <> null then prop.GetValue(o, null) :?> 'b
    else
      let meth = ty.GetMethod(s, BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic)
      let d,r = FSharpType.GetFunctionElements(typeof<'b>)
      typeof<DynamicHelper>.GetMethod("MkMethod").MakeGenericMethod([|d;r|]).Invoke(null, [| box meth; box o |]) :?> 'b

이를 통해 방법과 속성을 동적으로 호출 할 수 있습니다.

let (t:System.Type) = "test"?GetType()?BaseType
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top