tag remove practices name create commits commands best f# dispose idisposable resource-management

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.