나는 System.Linq.Expression 인스턴스를 반환하는 기능을 가지고 . 내 첫 번째 생각은 반환 형식을 명시 적으로 #Expression으로 표시하는 것이지만 작동하지 않습니다. 반환 유형을 가장 일반적인 유형으로 수동으로 변환하는 것을 포함하지 않는보다 우아한 방법이 있습니까?F #의 반환 형식 강제 변환
감사합니다.
편집 : 답변 해 주셔서 감사합니다. 명시 적 리턴 유형 + 업 캐스팅 시나리오를 사용하겠습니다. 여기
나는 System.Linq.Expression 인스턴스를 반환하는 기능을 가지고 . 내 첫 번째 생각은 반환 형식을 명시 적으로 #Expression으로 표시하는 것이지만 작동하지 않습니다. 반환 유형을 가장 일반적인 유형으로 수동으로 변환하는 것을 포함하지 않는보다 우아한 방법이 있습니까?F #의 반환 형식 강제 변환
감사합니다.
편집 : 답변 해 주셔서 감사합니다. 명시 적 리턴 유형 + 업 캐스팅 시나리오를 사용하겠습니다. 여기
몇 가지 방법은 당신이 선호 할 수 있습니다
open System.Linq.Expressions
type System.Object with
member this.ToExpression() : Expression = // explicit
match this with
| :? System.Int32 -> upcast Expression.Constant(this) // upcast
| :? System.Boolean -> Expression.Constant(this) :> _ // _
| _ -> failwith "bad expression"
명시 적으로 member
선언에 반환 유형을 명시함으로써, 당신은 신체, 예를 들어, 그것을 추론 할 수 _
을 통해 "이 유형을 추측 해주십시오"또는 upcast
연산자를 사용하여 제약 조건에서 위로 캐스팅 할 유형을 추론 할 수 있습니다.
저는이 글을 쓰는 훨씬 더 우아한 방법이 있다고 생각하지 않습니다.
컴파일러에서는 match
표현식의 모든 분기가 동일한 반환 유형을 가지며 암시 적으로 강제 변환을 삽입하지 않아야합니다. upcast
키워드를 사용하여 대상 유형을 지정하지 않고 강제 변환을 삽입 할 수 있습니다.이 경우 컴파일러는 유형 정보와 같은 다른 정보를 사용하여 유형을 결정하므로 형식을 반복하지 않아도됩니다.
and System.Object with
member this.ToExpression() : Expression =
match this with
| :? System.Int32 -> upcast Expression.Constant(this)
| :? System.Boolean -> upcast Expression.Constant(this)
| :? Tml.Runtime.Seq as s -> upcast s.ToExpression()
| _ -> failwith "bad expression"
표현식과 형식 주석 각각에 형식 주석과 upcast
을 추가 했으므로 F # 컴파일러는 upcast
이 결과를 Expression
으로 강제 변환해야한다고 추론합니다. 함수를 호출 할 때 컴파일러가 암시 적 강제 변환을 삽입 유일한 장소입니다, 그래서 당신은 또한 다음과 같은 쓸 수 있습니다 (하지만 난 그게 더 좋은 있는지 확실하지 않다) :
// Thanks to implicit coercions, we don't even need #type
let expr (a:Expression) = a
// and then for example:
| :? System.Int32 -> Expression.Constant(this) |> expr
, upcast
이 키워드입니다 따라서 파이프 라이닝과 함께 사용할 수 없으므로 이와 같은 함수를 정의하면 몇 가지 이점이있을 수 있습니다.
엄밀히 상수의 유형이기 때문에
open System.Linq.Expressions
let Constant obj = Expression.Constant(obj) :> Expression
type System.Object with
member this.ToExpression()
match this with
| :? System.Int32 -> Constant(this)
| :? System.Boolean -> Constant(this)
| _ -> failwith "bad expression"
이이 coersion을 제거하지 않고 내 의견으로는 (:) 너무 당신에게 입력을 조금 절약 할 수) 눈에 조금 더 나은 말하기 a '-> Expression은 두 경우 모두에서 작동합니다. 아래쪽은 당신이 사용하려고하는 각각의 Expression 팩토리 메소드에 대한 함수를 정의해야 할 필요가 있기 때문이다.