f# - remove - ¿Por qué es mejor usar que usar?
git tags best practices (4)
De acuerdo con la última oración en esta página de MSDN, se debe preferir using
. Lo he escuchado en otros lugares ( esta respuesta , por ejemplo). ¿Por qué es esto? Me doy cuenta de que el use
se agregó más tarde. Pero, ¿cuál es la diferencia? En la superficie, el using
parece más útil porque puedes controlar cuándo se llama a Dispose()
, y puedes ignorar explícitamente el valor encuadernado (por ejemplo, (fun _ -> ...)
) si es necesario.
También puede controlar cuándo invocar dispose con el use
, simplemente utilizando las construcciones de alcance habituales (como parens o begin
- end
), por ej.
let F() =
let x = 4
(
use file = System.IO.File.Open("foo.xml", System.IO.FileMode.Append)
let z = 4
printfn "file still open here"
)
printfn "file was already closed/disposed"
Pero creo que esto rara vez es útil. Creo que también es raro no querer nombrar / utilizar el objeto IDisposable
. use
es más sintácticamente conveniente, y el 95% del tiempo hace lo que necesita, así que creo que es por eso que es preferible.
Personalmente, prefiero use
para using
por la misma razón que prefiero
let a = some_expr
some_stuff_with_a
a
(fun a -> some_stuff_with_a) some_expr
Con el formulario de enlace, normalmente puede evitar un conjunto de paréntesis, y la asociación entre el identificador y el valor al que está vinculado se encuentra más cerca en el espacio y es más fácil de ver.
Un ejemplo contra el use
es mejor que using
:
using
es mejor que use
ya que el using
se puede escribir en una línea, mientras que el use
no.
Ejemplo,
xx
es una función que devuelve un valor mediante una función fct de un recurso que se abre mediante yy
utilizando el parámetro p
dado.
let xx p = using (yy(p)) (fun resource-> fct resource) // <-- this is OK
let xx p = (use resource = yy(p); fct resource) // <-- this is Not OK
Creo que la razón para preferir el use
es simplemente que la sintaxis es más simple. Muchos otros constructos de lenguaje podrían expresarse como funciones (por ejemplo, try .. with
, for
, while
, ...). Si los diseñadores de idiomas agregaron una sintaxis más simple, ¿por qué no usarla ...
Como escribí en la respuesta anterior a la que hizo referencia , puede controlar con precisión el alcance incluso cuando se usa. (Y de esta manera, puede usarlo incluso en constructores de declaraciones de clases de expresiones de objeto ). Pero la mayoría de las veces, el comportamiento automático es bueno (lo que hace que el constructo sea más simple que using
en C #).
Si use
o using
en situaciones en las que necesite controlar el alcance explícitamente es una cuestión de gusto personal. Si no te gusta el alcance explícito del use
(que se ve un poco raro, lo admito, pero funciona bien para mí), puedes usarlo.
EDITAR: en una declaración de clase, no puede, por ejemplo, escribir:
type Foo() =
use a = new Whatever()
// ...
porque el alcance de a
sería (posiblemente) toda la vida de la instancia. (Aunque creo que esto podría ser útil y podría agregar la implementación automática de IDisposable
a su tipo). Si utilizas el using
, no obtienes este tipo de problema.