F#输出参数和值类型

时间:2016-02-02 23:48:50

标签: f# c#-to-f#

如果我传递对象的引用,但是不接受结构或原语,则以下f#函数效果很好:

let TryGetFromSession (entryType:EntryType, key, [<Out>]  outValue: 'T byref) =
    match HttpContext.Current.Session.[entryType.ToString + key] with 
             | null -> outValue <- null; false
             | result -> outValue <- result :?> 'T; true

如果我尝试用C#调用它:

bool result = false;
TryGetFromSession(TheOneCache.EntryType.SQL,key,out result)

我得到The Type bool must be a reference type in order to use it as a parameter有没有办法让F#函数同时处理它们?

2 个答案:

答案 0 :(得分:8)

问题是null中的outValue <- null值将类型'T限制为引用类型。如果它有null作为有效值,则它不能是值类型!

您可以使用Unchecked.defaultOf<'T>来解决此问题。这与C#中的default(T)相同,它返回null(对于引用类型)或值类型的空/零值。

let TryGetFromSession (entryType:EntryType, key, [<Out>]  outValue: 'T byref) =
    match HttpContext.Current.Session.[entryType.ToString() + key] with 
    | null -> outValue <- Unchecked.defaultof<'T>; false
    | result -> outValue <- result :?> 'T; true

答案 1 :(得分:0)

我仍然认为这不是“漂亮”/自然的F#代码,并且可能会对以下内容做更多的宣传:

let myCast<'T> o = 
 match box o with
 | :? 'T as r -> Some(r)
 | _ -> None


let GetFromSession<'T> entryType key = 
 match HttpContext.Current.Session.[entryType.ToString + key] with 
 | null -> None
 | r -> myCast<'T> r

这也是一种“更安全”,并且(应该?)不会抛出任何异常,它会删除F#中的空值。在C#中它将返回并且也可以正常工作,但是None返回为null,如果有一些结果,那么它将是Some; - )

请注意,上述代码未经过测试,未在任何设置中运行甚至已编译,因此请将其视为伪代码。它甚至可能有其他问题......

检查: https://msdn.microsoft.com/en-us/library/dd233220.aspxhttp://fsharpforfunandprofit.com/posts/match-expression/

在最后一个链接上,特别是:匹配子类型

另一方面,我不喜欢从HttpContext到Session的整个层次的缺失检查是非空的,但那可能只是我......

使用无/部分

更新某些C#代码
var x = GetFromSession<MyTypeInSession>(entryType, key)?.Value??defaultValue;

绝对没有必要走完全阿拉伯语,从右到左阅读,从下到上用ifs和buts的金字塔方案,没有糖果或坚果,用于无效检查等等。

再次将代码视为伪代码......