2008-10-18 11 views

Respuesta

13

¿Ha visto cómo muchos desarrolladores no entienden realmente ref/salida?

Los uso donde realmente son necesarios, pero no de otra manera. Por lo general, solo son útiles si desea devolver efectivamente dos o más valores, en cuyo caso vale la pena al menos pensando en acerca de si hay alguna manera de hacer que el método solo haga una cosa. A veces, el uso de ref/salida es el enfoque más apropiado - los diversos métodos TryParse etc.

+1

Amen. Fui a un curso de capacitación C# hace años y había un grupo de "desarrolladores" en el grupo que simplemente no podían echar un vistazo a ref/out. –

+0

Supongo que ese grupo de "desarrolladores" nunca tuvieron que entender qué punteros eran. –

+0

Utilizo principalmente ref/out para el rendimiento; no hay forma de que copiar una estructura de 256 bytes 105840000 veces por segundo sea aceptable;) – TraumaPony

2

ref/salida significa automáticamente la mutabilidad y la programación funcional con los valores inmutables es de moda en estos días. Intente insertar una llamada a Dictionary.TryGetValue en una consulta LINQ. La API requiere declarar variables y arruina cualquier 'fluidez' en la API.

Eso no es decir que esta es "la razón", pero es un ejemplo de "una razón".

(Ver también

http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!181.entry

para el comentario sobre cómo los lenguajes funcionales frente a tales API.)

+0

ref/out implica la mutabilidad de las variables, pero no necesariamente los tipos de datos. (Normalmente lo uso con variables locales, por ejemplo.) La fluidez es interesante: TryXXX tiende a requerir un comportamiento diferente para las diferentes bifurcaciones, lo que realmente no conlleva la fluidez :( –

1

ref/salida también no funcionan con los delegados "Func", por lo que estas API estilo son menos composable/reutilizables con algunas otras API que usan delegados.

2

Confundir es probablemente la mejor razón. Confundir significa una menor capacidad de mantenimiento y una mayor probabilidad de introducir errores sutiles. Los veo en una vista similar a la declaración de flujo de control "goto". Si bien no es intrínsecamente malo por sí mismo, ha llevado a muchos programas imposibles de leer/comprender a lo largo de las décadas.

Manténgase alejado de cualquier cosa que puede hacer que el código sea más confuso, entonces tiene que ser.

Una vez dicho esto, las palabras clave existen probablemente porque los desarrolladores marco sierra necesidad de tales cosas. Úselos si no hay una solución adecuada, pero evítelos cuando pueda.

5

En mi opinión, que se consideran un olor código, porque en general no es una opción mucho mejor: devolver un objeto.

Si te fijas, en la biblioteca .NET que sólo se utilizan en algunos casos especiales, a saber TryParse -como escenarios donde:

  • que regresan una clase de boxeo que significaría un tipo de valor
  • la El contrato del método requiere que sea rápido, por lo que el boxeo/desembalaje no es una opción viable.
-2

no es el código de la complejidad razón suficiente?Compare:

int myValue; 
ReadFromSomewhere(ref myValue); 

Para:

int myValue = ReadFromSomewhere(); 
+0

¿Qué tal si quieres devolver 2 valores? A menudo es más fácil simplemente devolver 2 valores, usando argumentos de refrecuencia, entonces es para crear un objeto/estructura que solo se usará con el único propósito de llamar a una sola función. – Kibbee

+0

Cierto, pero no me refería a múltiples argumentos. tiempo preferiría una estructura si fuera el usuario de esa función. –

+0

¿Cómo es ese complejo? – TraumaPony

-1

Usted debe devolver los objetos es probablemente la razón más probable de que no sugieren el uso de ref o fuera.

"ref" realmente solo se debe utilizar al pasar valores escalares, pero veo personas que lo usan a menudo para objetos que se pasan por referencia de todos modos.

1

Solo un pensamiento, me parece que ref/out es útil cuando los argumentos capturan el estado de ejecución en el método de destino en lugar de capturar datos devueltos. Considere un escenario en el que desee obtener un mensaje de error de un servicio que devuelve un objeto Cliente.

Customer GetCustomerById(int id, out string errorMessage); 

Si este método falla, probablemente devuelva un objeto de Cliente nulo o genere una excepción. Sin embargo, si quiero saber la causa del error (¿validación? ¿Base de datos?), Utilizaría el argumento out. El argumento errorMessage aquí no tiene nada que ver con los datos, simplemente se usa para capturar lo que está mal con la ejecución del método.

Personalmente, si tengo un método que se espera que devuelva dos o más datos/valores esenciales, me gustaría replantear el diseño de mi código.

0

La razón por la que me dijeron es que el 1.0 GC tenía problemas cuando se utilizaba ref/out. El GC en 2.0 (y probablemente no 1.1 tampoco) no tiene esos problemas, así que normalmente asumiría que es un legado ahora no útil.

0

@TraumaPony Estaría bien si nos da una fuente (URL o algo así) para este .NET framework guidlines.

+0

Supongo que TraumaPony se referirá a este libro (o su predecesor): http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321545613/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid= 1224484809 & sr = 8-1 –

Cuestiones relacionadas