2009-10-06 8 views
11

En algunas situaciones utilizando C/C++, que puede indicar sintácticamente al compilador que una returnvalue se ignora deliberadamente:C# - Cómo indicar cuando se ignoran deliberadamente un valor de retorno

int SomeOperation() 
{ 
    // Do the operation 

    return report_id; 
} 

int main() 
{ 
    // We execute the operation, but in this particular context we 
    // have no use of the report id returned. 
    (void)SomeOperation(); 
} 

me parece que se trata de una feria la práctica, en primer lugar porque la mayoría de los compiladores no generarán una advertencia aquí, y en segundo lugar porque muestra explícitamente a los futuros desarrolladores que el autor hizo una elección consciente para ignorar el retorno. Hace que el rastro de pensamiento del autor no sea ambiguo.

Hasta donde yo sé, el compilador de C# no se quejará de los valores de retorno ignorados implícitamente, pero me gustaría saber si hay una convención similar para usar con el fin de hacer una indicación clara a otros desarrolladores.

EDIT:

En respuesta a algunas personas aquí que cuestiona el uso real de esta convención (o que sería una muestra de un mal diseño disponer de un método con un valor de retorno potencialmente importante).

Un ejemplo .NET vida real (que tal vez debería haber basado la cuestión desde el comienzo) es el objeto mutex :: WaitOne() contra la sobrecarga que no tiene argumentos. Solo volverá si el mutex se adquirió de forma segura, de lo contrario nunca volverá. El valor de retorno booleano es para las otras sobrecargas en las que puede terminar no estando en posesión del mutex cuando regresa.

Así lo largo de mi razonamiento, me gustaría indicar en mi código multi-hilo que he tomado la decisión de ignorar el retorno:

Mutex mtx = new Mutex(); 
(void)mtx.WaitOne(); 

Desde el returnvalue nunca puede ser otra cosa que 'verdadero'.

+0

Sin embargo existe y la sobrecarga de WaitOne que tiene un parámetro de tiempo de espera y que ca return false cuando el tiempo expira. –

+0

@Pop: ese es el punto de mi argumento. Quizás lo leíste mal. – sharkin

+0

@ R.A. ya que no está utilizando el valor de retorno (que siempre es cierto), eso significa que lo está ignorando, pero no hay convención para decir "lo estoy ignorando a propósito", también en su ejemplo el valor de retorno siempre puede ser ignorado por diseño, por lo que no se necesita una explicación adicional. –

Respuesta

10

sólo puedo pensar en una situación, cuando no se permite que un "valor de retorno" para ser ignorado en C#: cuando se produce un error. Esto debería proporcionarse lanzando una excepción, lo que hace que sea imposible ignorarlo.

En otros casos, es (o mejor: debe ser) completamente seguro y no huele mal para ignorar los valores de retorno.

EDIT:

todavía no puedo ver el punto. ¿Por qué debería esto mejorar el código? Especifica ignorar el valor de retorno por propósito al no asignarlo a una variable.

  • Si no necesita este valor en su código, todo está bien.
  • Si lo necesita, no podrá escribir su código.
  • Si hay un caso especial que debe manejarse y nunca debe ignorarse implícitamente, se debe emitir una excepción.
  • Si el método llamado no tiene un valor de retorno y se obtiene uno más tarde, debe estar diseñado para no romper el código existente que lo ignora. El código de llamada existente no cambia.

¿Olvidé un caso?

+1

Buena respuesta, ya que los códigos de error no se deben devolver en .Net, es seguro ignorar todos los otros valores, ya que solo deberían representar resultados de cálculo u otra información que no represente estados de error. –

+1

I ** muy en desacuerdo ** con 'es (...) no huele mal ignorar los valores de retorno', lee sobre [Pure] (http://msdn.microsoft.com/en-us/library/ atributo system.diagnostics.contracts.pureattribute (v = vs.110) .aspx) para los métodos. No usar un valor de retorno de un método puro es seguramente un error. P.ej. escribir 'startDate.AddDays (1)' deja 'startDate' intacto y devuelve una nueva fecha que es un día en el futuro, e ignorar que la nueva fecha indica que el desarrollador cree que startDate ha cambiado. – ANeves

+0

@ANeves: a menos que el programador malinterprete completamente lo que realmente está haciendo un método (que debería resolverse nombrando correctamente), no puede continuar sin usar el valor de retorno. Entonces, ¿por qué debería calcular una fecha + 1 día y no usar el resultado? Si no lo usa, no necesita calcularlo. Usted dice que no es obvio para todo el mundo lo que AddDays está haciendo en realidad. Pero, ¿cómo se relaciona esto con la pregunta sobre el valor de retorno? Es un problema de nombres. –

7

El compilador Microsoft C# no genera una advertencia en ignorar las devoluciones. Que no necesita ya que hay un recolector de basura por lo que no habrá ninguna pérdida de memoria debido a ignorar objetos devueltos (a menos que sean IDisposable por supuesto). Por lo tanto, no es necesario "anular" explícitamente el compilador.

EDIT: Además, creo que el problema de "mantenimiento" es más como un problema de documentación y práctica de nombres. Entiendo que esto era sólo un ejemplo, pero no se esperaría un método llamado SomeOperation para devolver un ReportId. Se podría, sin embargo, es de esperar un método GetReportId para devolver una ReportId sin tener una gran cantidad de efectos secundarios. De hecho, ignorar el valor de retorno de un método llamado GetReportId sería bastante extraño. Por lo tanto, asegúrese de nombrar bien sus métodos y las personas no tendrán dudas sobre los efectos de sus llamadas a funciones.

EDIT 2: En este ejemplo de mutex, creo que el uso correcto no estaría ignorando el valor de retorno. Incluso si la implementación actual no volverá falsa, creo que es una buena práctica todavía comprobar el valor de retorno, en caso de que el resultado final será utilizando otra aplicación en el futuro o que cambien el comportamiento en futuras versiones de .NET Framework o algo:

if (mutex.WaitOne()) 
{ 
    // Your code here 
} 
else 
{ 
    // Optionally, some error handling here 
} 
+0

Entendido. Pero como mencioné en la pregunta, me gustaría usar la convención para indicar explícitamente a otros desarrolladores que ignoro el retorno a propósito. Lo actualizaré para que quede más claro. – sharkin

+0

En respuesta a su edición, vea mi actualización de la pregunta. – sharkin

0

No tengo convenciones estándar que yo sepa.

Pero estoy luchando para encontrar una buena razón para necesitar esto. Parece que SomeOperation() debería ser realmente dos métodos separados. ¿Tienes un ejemplo de un método que realmente debería comportarse de esta manera? ¿Por qué debería un método molestarse en devolver un resultado si se va a ignorar?

+0

Actualicé la pregunta con un ejemplo. – sharkin

+1

¿Realmente va a refactorizar solo porque hay un lugar donde no necesita el valor de retorno de una función? Personalmente, * podría * escribir una pequeña función que simplemente llame a la existente usando una variable ficticia local para el resultado, pero no devuelve nada en sí misma, pero es muy probable que no. Claro, estoy de acuerdo, ¿por qué devolver un resultado si va a ser ignorado, pero de nuevo ¿por qué tener dos funciones casi idénticas? ¿Y por qué preferir una optimización prematura para limpiar, un código mínimamente desordenado? Además, la función puede estar en línea y optimizada por el compilador de todos modos. – Steve314

+0

Steve314 - No estaba diciendo que deba requerir un refactor. Estaba tratando de insinuar que esto me pareció un olor codificado. Por lo tanto, quería asegurarme de que este fuera un problema real, no solo uno creado por otra cosa. –

0

A veces es útil poder colocarlo (vacío) para indicarle a un codificador futuro que está mirando el código que usted sabe perfectamente que devuelve algo, y lo está ignorando deliberadamente.

Dicho esto, el compilador de C# tendrá un error en la sintaxis.

0

que he visto:

var notUsed = SomeOperation(); 

No es tan aficionado a él sin embargo.

+0

Este enfoque desencadenará la regla de Análisis de código [CA1804: Eliminar locales no utilizados] (https://msdn.microsoft.com/en-us/library/ms182278.aspx). – DavidRR

1

object dummy = JustDontCare();

+1

El nombre tradicional es variable "ficticia". – Steve314

+1

-1 para usar una variable. ¿Por qué no solo suelta el valor de retorno? –

+0

(de Chris KL) ... para indicarle a un codificador futuro que está mirando el código que usted sabe perfectamente que devuelve algo, y lo está ignorando deliberadamente. – wefwfwefwe

0

La convención en .Net es, si no almacenar o utilizar un valor de retorno que significa que no hace caso de manera implícita, no hay convención explícita, y la API es generalmente diseñado para devuelven valores pueden ser generalmente ignorado, con la excepción de los valores booleanos que representan el fracaso, el estado de éxito.

Pero incluso en el caso de valores de retorno booleanos que representan el estado de éxito/falla, la convención es que si ignoras el valor de retorno (no lo usas) significa que el código no depende del estado de éxito de llamada.

+1

Aprecio el hecho de que algunas cosas son prácticas comunes en C#, pero cuando se habla en general (en particular para grandes proyectos), la calidad del código siempre aumenta cuando el rastro de pensamiento del autor es explícito y no ambiguo. – sharkin

+2

Bueno, si le preocupa la calidad del código, ignorar los valores de retorno que pueden ignorarse "de manera segura" y que no son necesarios no aumenta la calidad del código. Si se necesita una explicación de por qué se ignora el valor, excepto que no es necesario, entonces un comentario sería más adecuado, ya que explicaría el "por qué", y no establecería lo obvio "el valor se ignora". No existe una convención para establecer lo obvio (se ignora el valor de retorno), ya que ignorar el valor de retorno rara vez es un error, generalmente es por elección en .Net. –

12

Si desea indicar a otros desarrolladores y dejar en claro que el valor de retorno se ignora intencionalmente, simplemente coméntelo.

SomeMethod(); // return value ignored - $REASON 
Cuestiones relacionadas