如果我传递对象的引用,但是不接受结构或原语,则以下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#函数同时处理它们?
答案 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.aspx 和 http://fsharpforfunandprofit.com/posts/match-expression/
在最后一个链接上,特别是:匹配子类型
另一方面,我不喜欢从HttpContext到Session的整个层次的缺失检查是非空的,但那可能只是我......
使用无/部分
更新某些C#代码var x = GetFromSession<MyTypeInSession>(entryType, key)?.Value??defaultValue;
绝对没有必要走完全阿拉伯语,从右到左阅读,从下到上用ifs和buts的金字塔方案,没有糖果或坚果,用于无效检查等等。
再次将代码视为伪代码......