2009-03-09 13 views
13

Imagínese que alguien codificación de los siguientes:compilador de C# Mejora de sugerencias

string s = "SomeString"; 
s.ToUpper(); 

Todos sabemos que en el ejemplo anterior, la llamada al método “ToUpper()” no tiene sentido porque la cadena devuelta no se maneja en absoluto . Pero, sin embargo, muchas personas cometen ese error y pasan el tiempo tratando de solucionar cuál es el problema preguntándose "¿por qué los caracteres de mi 'mayúscula' no están en mayúscula?"

Entonces, ¿no sería genial si hubiera un atributo que podría aplicarse al método "ToUpper()" que produciría un error de compilación si no se maneja el objeto devuelto? Algo parecido a lo siguiente:

[MustHandleReturnValueAttribute] 
public string ToUpper() 
{ 
… 
} 

Si Para que este código para compilar correctamente el usuario tendría que manejar el valor de retorno de esta manera:

string s = "SomeString"; 
string uppers = s.ToUpper(); 

Creo que esto sería dejar muy claro que debe manejar el valor de retorno; de lo contrario, hay sin punto al llamar a esa función.

En el caso del ejemplo de cadena esto puede no ser un gran problema, pero puedo pensar en otras razones más válidas de por qué esto sería útil.

¿Qué piensan?

Gracias.

+0

Lo he hecho antes, +1 –

+0

@Rene: punto válido, +1 – Codex

Respuesta

8

¿Se puede llamar a un método por sus efectos secundarios, por su valor de retorno o por ambos? Las funciones "puras" (que no tienen ningún efecto y solo sirven para calcular un valor de retorno) serían buenas para anotar como tales, tanto para eliminar el tipo de error que describes como para habilitar algunas posibles optimizaciones/análisis. Quizás en otros 5 años veremos que esto suceda.

(Tenga en cuenta que el F # compilador le advertirá cualquier momento se ignora implícitamente un valor de retorno. La función 'ignorar' se puede utilizar cuando se quiere hacer caso omiso de forma explícita.)

+0

Generalizar la noción de anotaciones de "pureza" sería bueno, porque entonces el compilador podría optimizar más. Similar a la palabra clave const C++, realmente. – Thomas

+0

Además, al agregar una anotación [Pura] se resolverían los problemas a los que la gente habla a continuación cuando llaman funciones y no les importan los efectos secundarios. Supongo que eso es a lo que realmente llegaba el autor. – Mason

0

Al menos una advertencia del compilador sería útil. Quizás agreguen algo similar para C# 4.0 (Design-By-Contract).

+0

Prefiero una advertencia sobre un error. Si solo estás lanzando código, no querrás que esto te impida ejecutar el código, por ejemplo. – Andy

+0

El diseño por contrato se trata de precondiciones, condiciones posteriores e invariantes. No se trata de establecer términos sobre cómo se pueden/deben usar los valores devueltos. –

0

Esto no garantiza de una advertencia o pragma. Hay demasiados lugares en los que se pretende descartar el resultado, y me fastidiaría recibir una advertencia/error del compilador solo porque el método estaba decorado con algún atributo de esquivar.

Este tipo de 'advertencia' debe anotarse en el Editor del IDE, como un pequeño ícono en la cuneta "Advertencia: descartar el valor de retorno" o similar.

2

No estoy seguro de que me gusta esto. He llamado a muchos métodos que devuelven un valor que elijo no capturar. Agregar algún tipo de valor predeterminado (el compilador genera una advertencia cuando no se maneja un valor devuelto) me parece incorrecto.

Estoy de acuerdo en que algo a lo largo de las líneas sugeridas podría ayudar a los nuevos programadores, pero agregar un atributo en este punto solo afectará una cantidad muy pequeña de métodos en relación con el gran cuerpo existente. Ese mismo programador junior nunca sabrá qué hacer con el problema cuando el compilador no marque la mayoría de sus valores de devolución no controlados.

Podría haber sido un buen camino de vuelta cuando los caballos están fuera del granero.

+0

Agregar un atributo sería un poco demasiado, pero no veo por qué el compilador no puede dar una advertencia de "Código no tiene efecto". –

+0

El problema para mí es que estás tomando una construcción válida y haciendo que genere una advertencia. Sí, puede ser confuso pero sí uso métodos que devuelven valores todo el tiempo sin capturar dicho valor devuelto. – andleer

+0

bool DoStuff() {doStuff(); if (success) return true; falso retorno; } Ahora cuando llamo a DoStuff() puede haber ocasiones en que no me preocupe el éxito o el fracaso. No es necesario verificar los resultados, incluso si se consideran devueltos. Otras veces, seguro, me podría importar. – andleer

6

Si tiene Resharper, resaltará cosas como esta para usted. No puedo recomendar el reafilador lo suficiente, tiene muchas adiciones IDE útiles, especialmente en torno a la refactorización.

http://www.jetbrains.com/resharper/

1

me gustaría en realidad prefiere una forma de bandera de una estructura o clase como [inmutable], y tener esta manejado de forma automática (con una advertencia) para los métodos llamados sin necesidad de utilizar sus valores de retorno de los objetos inmutables. Esto también podría proteger el objeto por el compilador de los cambios después de la creación.

Si el objeto es realmente un objeto inmutable, realmente no habría forma de manejarlo. También podría ser utilizado por los compiladores para detectar otros errores comunes.

Etiquetar el método en sí me parece menos útil. Estoy de acuerdo con la mayoría de los otros comentarios al respecto. Si el objeto es mutable, llamar a un método podría tener otros efectos secundarios, por lo que el código anterior podría ser perfectamente válido.

1

Tengo flashbacks para poner (vacíos) lanzamientos en todas las llamadas printf() porque no pude hacer que Lint se callera sobre el valor de retorno que se ignora.

Dicho esto, parece que esta funcionalidad debería estar en alguna herramienta de comprobación de código en lugar de en el compilador.