Para el programa de ejemplo:tipo no tiene null como un valor adecuado
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
me sale el error "El tipo 'MiClase' no tiene nulo como un valor apropiado" cuando vaya a utilizar esta clase como valor de retorno de las funciones implícitamente tipadas y compárelo con null (b/c de requisitos de compatibilidad con la inyección de dependencia C# No puedo confiar en los tipos de opción F #).
puedo solucionar este cambiando el cheque nulo:
if instance :> obj = null then
Sin embargo, sé ("sentir") esto es completamente "equivocado". Especialmente cuando considero cómo MyClass es un tipo de referencia que no debería estar encasillado (hablando desde un fondo de C#).
He leído sobre "F # Value Restriction" y cómo afecta la inferencia de tipo, pero parece que no puedo ver cómo se aplica a este escenario.
P: ¿Hay alguna otra manera de hacerlo?
Aparte # 1: He encontrado un método más sencillo de conseguir el error ...
type public MyClass(reasonForLiving:string) =
member x.ReasonForLiving with get() = reasonForLiving
let nullMyClass : MyClass = null
Aparte # 2: Yo probé System.Nullable sin pensar ... es un MiClase tipo de referencia y no un tipo de valor (struct) que requiere Nullable < _>. Entonces, solo me asegura que REALMENTE estoy tratando con un tipo de referencia y me hace preguntarme por qué un objeto lanzado de repente hace que esto funcione.
Actualización: Para cualquier persona interesada, utilicé esto como una solución para el Localizador de servicios comunes con las tres funciones siguientes. Cada servicio solicitado debe ser compatible con nula, por lo que si la clase de servicio se define en Fa #, es necesario agregar la [<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! Después de ver esto, lo reconocí de la tercera oración en MSDN "Null Values (F #)": http://msdn.microsoft.com/en-us/library/dd233197(v=vs.110).aspx –
Solo para add - es más idiomático usar 'Option 't' si no hace interop –
John - Sí, he mencionado que no puedo usar Option. Por lo tanto, casi todas las clases expuestas a C# necesitarían '[]' trabajar como se esperaría un desarrollador de C# ... :( –