2012-02-17 22 views
18

Escribo con frecuencia código C# que tiene que usar cadenas mágicas para expresar nombres de propiedades. Todos conocen los problemas con las cuerdas mágicas. Son muy difíciles de refactorizar, no tienen tiempo de compilación y a menudo conducen a problemas difíciles de diagnosticar. Sin embargo, C# /. NET los usa en todo el lugar para representar los nombres de propiedad/clase/método.Reflejo de tiempo de compilación en C#

Este problema ha persistido durante años y años, y la única solución viable actualmente es utilizar un árbol de expresiones que luego se analiza en tiempo de ejecución para el nombre de la propiedad. Esto le proporciona una verificación satisfactoria en tiempo de compilación, pero complica el código (que requiere parámetros de tipo Expresión), y, incurre en un costo en tiempo de ejecución.

¿Alguien sabe si alguna vez ha habido una consideración de función para C# /. NET para agregar una reflexión en tiempo de compilación para superar este problema omnipresente?

Parece que sería una adición fácil de realizar, sería un cambio sin interrupciones, y sería muy beneficioso para muchos desarrolladores. El operador typeof() ya realiza una forma de reflexión en tiempo de compilación, por lo que parece que un nombre de operador de() (o algo similar) sería muy elogioso.

Además, ¿alguien sabe de algún problema potencial con tal característica?

Gracias por la ayuda.

+0

posible duplicado de [Uso de una expresión lambda para evitar el uso de una "cadena mágica" para especificar una propiedad] (http://stackoverflow.com/questions/3330758/using-a-lambda-expression-to-avoid-using -a-magic-string-to-specify-a-property) –

+1

Ver también: [Obtener la propiedad, como una cadena, de una Expresión >] (http://stackoverflow.com/questions/2789504/get-the-property-as-a-string-from-an-expressionfunctmodel-tproperty) –

+3

@KirkWoll Esto no es un duplicado de esa pregunta. El segundo párrafo de la pregunta indica que MgSam está familiarizado con la técnica de árbol de expresión; la pregunta es si puede haber una nueva característica en las obras que permita una nueva solución al problema. – phoog

Respuesta

11

Straight from the source - esta es una publicación de blog realizada por un diseñador de lenguaje C#, y el "Usuario" en esta publicación pregunta acerca de las mismas preguntas que usted y recibe una respuesta. El autor dice que sería necesario especificar una sintaxis para cada elemento de metadato que quisiera pedir y no es trivial, es decir. ¿Qué sobrecarga quieres, si quieres el método "info-of" y el método está sobrecargado? ¿Qué pasa si hay implementaciones genéricas e interfaces explícitas involucradas? Y así. Resulta que, si bien no se consideró digno de implementación en 2009 debido a esas razones, lo obtendremos en C# 6 en 2015 - vea C# Language Design Notes for Jul 9, 2014.

+1

Bueno, es una publicación de blog de un diseñador de lenguaje C# sobre problemas reales con la implementación de un "infoof () "operador que funciona como typeof pero para cualquier metadato (método, propiedad, etc.). OP hace las mismas preguntas que "Usuario" del artículo y el "Usuario" obtiene todas las respuestas. – cynic

+2

La respuesta de Eric parece implicar que el uso de expresiones ha resuelto el problema. Pero muchas de las tecnologías de Microsoft usan cadenas mágicas para representar clases/propiedades: ASP .NET (formularios web y MVC), Silverlight, WPF, Winforms; todos los usan. Sin mencionar desarrolladores de terceros cuyas bibliotecas puedes confiar. Y si buscas lo suficiente, encontrarás bibliotecas centrales que también las usan. Para mí, esto parece ser un problema más generalizado (y uno más fácil de abordar) que el problema que resuelven las palabras clave async/await. – MgSam

+1

No creo que sean las respuestas de los correos las razones por las que no se pueden sobrecargar las propiedades. – ja72

0

Sin embargo, C# /. NET los utiliza por todos lados para representar los nombres de propiedad/clase/método.

Primero: no estoy de acuerdo. Existen ciertos marcos (WebForms, por ejemplo) que utilizan cadenas mágicas en todas partes, pero las bibliotecas base para C# y .NET tienden a evitar estas cosas notablemente bien.

En segundo lugar: en muchos casos donde se utilizan cadenas mágicas, ReSharper puede reconocer errores. Esto puede ayudar bastante.

Finalmente: lo que está pidiendo puede ser posible a través del Compilador Roslyn, que promete proporcionar "Compilación como servicio".

+1

Estoy de acuerdo en que las librerías de .NET centrales se mantienen alejadas de las cadenas mágicas, pero si has mirado MVC3 en absoluto, oh hombre, es el infierno de MagicString :) Gracias a Dios por la habilidad de ReSharper para decirte si escribiste un controlador o acción incorrectos nombre en un parámetro de cadena! – CodingWithSpike

+1

El compilador ya conoce toda la información relevante durante el tiempo de compilación para que esta característica sea posible. Según tengo entendido, Roslyn simplemente permitirá a los terceros obtener más fácilmente ideas similares sobre el código antes del tiempo de compilación. – MgSam

+1

@MgSam: Roslyn parece permitir configurar sus propias reglas de compilación, por lo que podría permitir escribir un árbol de expresiones en un código que se convierta en un nombre de método, nombre de controlador, etc. en tiempo de compilación. – StriplingWarrior

6

Estaba teniendo un problema similar. Recientemente descubrió que .NET Framework 4.5 tiene una función llamada los atributos Caller Info. Al usar estos, puede obtener información sobre la persona que llama a un método en tiempo de compilación. Puede obtener la ruta del archivo del código fuente, el número de línea en el código fuente y el nombre del usuario que llama.

public void DoProcessing() 
{ 
    TraceMessage("Something happened."); 
} 

public void TraceMessage(string message, 
     [CallerMemberName] string memberName = "", 
     [CallerFilePath] string sourceFilePath = "", 
     [CallerLineNumber] int sourceLineNumber = 0) 
{ 
    Trace.WriteLine("message: " + message); 
    Trace.WriteLine("member name: " + memberName); 
    Trace.WriteLine("source file path: " + sourceFilePath); 
    Trace.WriteLine("source line number: " + sourceLineNumber); 
} 
7

En C# 6.0, un nuevo operador, nameof, se está agregando que le permitirá obtener los nombres de las propiedades, clases, campos, eventos, y variables en tiempo de compilación.

Link to the design notes

No más de reflexión para la información que el compilador ya sabe en tiempo de diseño!

Cuestiones relacionadas