Dla przykładowego programu:Rodzaj nie mają zerowy jako właściwą wartość
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
pojawia się błąd „typu«MojaKlasa»nie mają zerowy jako właściwą wartość” Kiedy idę do korzystania z tej klasy jako wartość zwracana niejawnie wpisanych funkcji i porównaj ją z null (b/c wymagań zgodności z wtryskiem zależności C# nie mogę polegać na typach opcji F #).
mogę łatwo rozwiązać ten problem poprzez zmianę czek wartości null do:
if instance :> obj = null then
Jednak wiem („czuć”) jest to całkowicie „źle”. Zwłaszcza, gdy zastanawiam się, w jaki sposób MyClass jest typem odniesienia, który nie powinien być zapakowany (mówiąc z tła C#).
Czytałem o "Ograniczeniu wartości F #" i jego wpływie na wnioskowanie o typie, ale nie mogę wyobrazić sobie, jak to dotyczy tego scenariusza.
P: Czy jest inny sposób na zrobienie tego?
Oprócz # 1: znalazłem prostszy sposób uzyskiwanie błąd ...
type public MyClass(reasonForLiving:string) =
member x.ReasonForLiving with get() = reasonForLiving
let nullMyClass : MyClass = null
Poza # 2: Próbowałem System.Nullable bez zastanowienia ... MojaKlasa jest typ odniesienia, a nie typ wartości (struct) wymagany przez Nullable < _>. Tak więc, tylko upewniam mnie, że NAPRAWDĘ mam do czynienia z typem referencyjnym i sprawia, że zastanawiam się, dlaczego obiekt nagle rzuca się w oczy.
Aktualizacja: Dla wszystkich zainteresowanych użyłem tego jako jednego rozwiązania dla wspólnego serwisu usługowego z trzema funkcjami poniżej. Każdy wniosek musi obsługiwać NULL, więc jeśli klasa usług jest określona w F # usługi, trzeba by dodać [<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! Po obejrzeniu tego, rozpoznałem go z trzeciego zdania na MSDN "Null Values (F #)": http://msdn.microsoft.com/en-us/library/dd233197(v=vs.110).aspx –
Tylko add - używanie opcji 'Option 't' jest bardziej idiomatyczne, jeśli nie robisz interakcji –
John - Tak, wspomniałem, że nie mogę używać opcji. Tak, prawie każda klasa narażona na C# potrzebuje '[]' do pracy jako programista C#, który oczekiwałby ... :( –