代码之家  ›  专栏  ›  技术社区  ›  Nick Randell

C和F投射-特别是“as”关键字

  •  23
  • Nick Randell  · 技术社区  · 15 年前

    在C中,我可以做到:

    var castValue = inputValue as Type1
    

    在F,我可以做到:

    let staticValue = inputValue :> Type1
    let dynamicValue = inputValue :?> Type1
    

    但它们都不是C关键字的等价物 as .

    我想我需要为f中的等价物做一个匹配表达式。#

    match inputValue with
    | :? Type1 as type1Value -> type1Value
    | _ -> null
    

    这是正确的吗?

    5 回复  |  直到 7 年前
        1
  •  25
  •   Tomas Petricek    15 年前

    据我所知,f没有任何内置的运算符等价于c# as 所以你需要写一些更复杂的表达式。或者使用 match ,您也可以使用 if ,因为操作员 :? 使用方法与 is C中:

    let res = if (inputValue :? Type1) then inputValue :?> Type1 else null
    

    当然,您可以编写一个函数来封装这种行为(通过编写一个简单的通用函数 Object 并将其强制转换为指定的泛型类型参数):

    let castAs<'T when 'T : null> (o:obj) = 
      match o with
      | :? 'T as res -> res
      | _ -> null
    

    此实现返回 null ,因此它要求类型参数具有 无效的 作为适当的值(或者,您可以使用 Unchecked.defaultof<'T> ,相当于 default(T) 在c)中。现在你可以只写:

    let res = castAs<Type1>(inputValue)
    
        2
  •  10
  •   Tahir Hassan    10 年前

    我会使用一个活跃的模式。这是我用的:

    let (|As|_|) (p:'T) : 'U option =
        let p = p :> obj
        if p :? 'U then Some (p :?> 'U) else None
    

    这是一个示例用法 As :

    let handleType x = 
        match x with
        | As (x:int) -> printfn "is integer: %d" x
        | As (s:string) -> printfn "is string: %s" s
        | _ -> printfn "Is neither integer nor string"
    
    // test 'handleType'
    handleType 1
    handleType "tahir"
    handleType 2.
    let stringAsObj = "tahir" :> obj
    handleType stringAsObj
    
        3
  •  5
  •   kvb    15 年前

    您可以创建自己的运算符来执行此操作。这实际上与Tomas的例子相同,但显示了一种稍微不同的方法来调用它。下面是一个例子:

    let (~~) (x:obj) = 
      match x with
      | :? 't as t -> t //'
      | _ -> null
    
    let o1 = "test"
    let o2 = 2
    let s1 = (~~o1 : string)  // s1 = "test"
    let s2 = (~~o2 : string) // s2 = null
    
        5
  •  1
  •   knocte    7 年前

    我想我需要为f中的等价物做一个匹配表达式。#

    match inputValue with | :? Type1 as type1Value -> type1Value | _ -> null

    这是正确的吗?

    是的,没错。(我认为你自己的答案比其他答案更好。)