對於樣本程序:類型沒有空作爲一個適當的值
type public MyClass(reasonForLiving:string) =
member x.ReasonForLiving with get() = reasonForLiving
let classFactory() = MyClass("up to you")
let live() =
let instance = classFactory()
if instance = null then raise(System.Exception("null is not living... that's why OO languages die from bugs"))
instance
我得到錯誤「的類型‘MyClass的’沒有空作爲一個適當的值」,當我去使用這個類作爲隱式類型函數的返回值,並將其與null(與C#依賴注入的兼容性需求的b/c不能依賴於F#選項類型)進行比較。
我可以很容易地通過改變空校驗解決這個問題:
if instance :> obj = null then
但是,我知道(「感覺」)這完全是「錯誤的」。特別是當我考慮MyClass如何是一個不需要裝箱的引用類型時(從C#背景來講)。
我讀過關於「F#值限制」以及它如何影響類型推斷,但我似乎無法看到它如何適用於這種情況。
問:是否有其他方法可以做到這一點?
除了#1:我發現得到的錯誤的一個更簡單的方法...
type public MyClass(reasonForLiving:string) =
member x.ReasonForLiving with get() = reasonForLiving
let nullMyClass : MyClass = null
除了#2:我也嘗試System.Nullable不假思索... MyClass的是引用類型,而不是可空值< _>所需的值類型(結構)。所以,只是讓我確信我真的在處理一個引用類型,並讓我想知道爲什麼一個對象會突然產生這個工作。
更新:對於任何有興趣的人,我將它作爲Common Service Locator的一個解決方案,並具有以下三個功能。要求必須支持空,所以如果服務類在F#中定義的每個服務,您需要添加[<AllowNullLiteral>]
:
let private getServiceLocator() =
try Some(Microsoft.Practices.ServiceLocation.ServiceLocator.Current)
with | _ -> None
let private getService serviceFactory =
let serviceLocator = getServiceLocator()
let service = match serviceLocator with
| None -> serviceFactory()
| _ ->
match serviceLocator.Value.GetInstance<'a>() with
| null -> serviceFactory()
| svc -> svc
match service with
| null -> None
| _ -> Some(service)
let private getRequiredService serviceFactory =
let service = getService serviceFactory
match service with
| None -> raise(MissingServiceException(""))
| _ -> service.Value
Doh!看到這個之後,我從MSDN的第三句話「空值(F#)」中識別出它:http://msdn.microsoft.com/en-us/library/dd233197(v=vs.110).aspx – 2012-07-27 22:35:09
只是爲了添加 - 如果你不做互操作,使用'Option't'會更習慣使用 – 2012-07-27 22:44:10
John - 是的,我提到無法使用Option。因此,幾乎所有暴露給C#的類都需要'[]'作爲C#開發人員期望的工作...... :( –
2012-07-27 22:45:12