2010-11-11 21 views

Respuesta

13

Porque cuando busca su campo (como en esa pregunta) usa la representación de cadena "Id". Una vez que se haya cambiado, tu reflejo se colapsará.

Lo que sugiere es Darin tipos estáticos:

Expression<Func<Program, int>> expression = p => p.Id; 

Ves eso? Esta es una característica interesante, pero no muy conocida, del compilador C# 4.0: automáticamente crea el árbol de expresiones a partir de la expresión lambda y lo convierte al Expression<T>. Entonces, más tarde puede atravesarlo y obtener MemberInfo de Id. Pero no es tan universal como Reflection porque no puede buscar por string.

+6

Y funciona mejor con herramientas de refactorización automáticas ya que saben que se refiere a una propiedad determinada y no es una cadena opaca. – CodesInChaos

+0

¿Hay alguna diferencia en la velocidad? – hkon

+0

@hkon algunos. no tiene que buscar 'MemberInfo' – Andrey

1

De mi conocimiento limitado de .NET, la forma de árbol de expresión parece hacer la verificación de tipo.

5

La pregunta que se plantea es por qué los árboles de expresión son más seguros que la reflexión.

La respuesta es que son ambos utilizando la reflexión.

Editar para aclarar: MemberInfo.GetCustomAttributes es una llamada de reflexión.

http://msdn.microsoft.com/en-us/library/system.reflection.memberinfo.getcustomattributes(VS.71).aspx

+1

Hay alguna diferencia en seguridad, por lo que está equivocado. – Andrey

+0

Llegar al punto para llamar a la reflexión es tipear seguro, y es un buen truco. Sin embargo, el resultado final en ambos casos es una llamada de reflexión a System.Reflection.MemberInfo.GetCustomAttributes – asawyer

+0

. La pregunta es cómo son diferentes, no cómo son similares. – Andrey

0

Si estamos hablando de la seguridad de tipos y romper el código al cambiar el nombre propiedades, por ejemplo, el árbol de expresión "ventaja" es negado ahora que tenemos nuevas características de C# como nombredel():

de expresión manera de árbol (era mejor antes nombredel()):

Expression<Func<YourClass, int>> expression = p => p.Id; 
var memberExpression = (MemberExpression)expression.Body; 
var property = ((PropertyInfo)memberExpression.Member); 

GetProperty de nombre (antes era malo nombredel()):

var property = typeof(YourClass).GetProperty(nameof(YourClass.Id)); 

La entrada de cadena en GetProperty no era segura, ya que estaba codificada como "Id", y cuando renombró la propiedad Id, su código se rompería en tiempo de ejecución si no recordaba reemplazar también esta cadena.

Eso hizo que los árboles de expresión sean más seguros, porque usaste el nombre real de la propiedad.

Pero ahora que tenemos nameof(), la cadena utilizada es en realidad el nombre de la propiedad en tiempo de compilación, y si cambia el nombre de la propiedad, y usted/su IDE "olvida" cambiarle el nombre en el fragmento anterior también , el código se romperá en el tiempo de compilación.

Así que ahora el viejo "mal camino" es más conciso en mi opinión y probablemente también rinda un poco mejor, ya que no necesita el casting extra.

Cuestiones relacionadas