2012-08-30 10 views
9

Duplicar posibles:
Can I change a private readonly field in C# using reflection?Ajuste campos de sólo lectura (¿Es este error?)

mientras que sólo jugando con C#, se dio cuenta de una cosa extraña.

Aquí está el código:

class Program 
{ 
    static void Main(string[] args) 
    { 
     System.Diagnostics.Debug.Write(string.Empty); 

     typeof(string) 
      .GetField("Empty", BindingFlags.Static | BindingFlags.Public) 
      .SetValue(null, "Tolgahan"); 


     Console.WriteLine(string.Empty); 

     // output : Tolgahan 
    } 
} 

Por qué reflexión vamos nosotros para cambiar los campos de sólo lectura?

ACTUALIZACIÓN: La pregunta era "por qué se permite la configuración mediante reflexión", no "cómo hacerlo", por lo que no es un duplicado.

+4

Puede hacer todo tipo de cosas con la reflexión que no puede hacer normalmente. Puede obtener/configurar campos privados de otras clases, por ejemplo. Estoy casi seguro de que esto no es un error; en cuanto a si es deseable es otra historia. – Servy

+3

Para robar una cita, solo tiene que protegerse contra "Murphy, no Maquiavelo" –

+0

@Dennis: La otra pregunta simplemente pregunta si es posible, esta afirma que es posible, pero pregunta por qué (y por lo tanto es mucho más valiosa que el otro). –

Respuesta

14

De la misma manera las leyes de la química dicen que ninguna reacción puede causar que un átomo de un elemento se convierta en un átomo de otro elemento, pero las leyes de la física dicen que sucede todo el tiempo. La química es un subconjunto restringido de la física con el fin de simplificar los problemas de una manera más solvable.

La reflexión es la física en este caso, donde la programación normal es la química. Opera en una mentalidad más simple. La reflexión le permite eludir ese conjunto de reglas más simple, exponiéndolo a nuevos procesos, pero también a nuevos peligros.

+2

¡Qué metáfora extraña! No, no es un error suficiente, ¿o es eso demasiado químico? – Jodrell

+3

Intenta leerlo en la voz de Bryan Cranston, de repente comienza a tener sentido. –

+0

@ssg Más sentido que el de Aaron Paul, al menos :-) – corsiKa

0

Es posible porque Reflection en .Net se implementó de esta manera. Solo puedo adivinar la motivación para esto, pero es una herramienta poderosa (pero lenta) que ofrece gran flexibilidad y potencial para el uso indebido.

No es la única forma en que se puede lograr tal alteración, pero tales discusiones están fuera de tema y fuera de lugar como cualquier otra especulación subjetiva.

3

Porque readonly, como private, protege contra Murphy, no Machiavelli *.

Usamos readonly y private y cualquier otra cosa que restrinja lo que podemos hacer, principalmente porque con suerte hemos restringido las cosas más incorrectas, inconsistentes o simplemente estúpidas, que tenemos cosas útiles y fructíferas.

Pero son solo unos y ceros. Si alguna memoria está configurada en el número "42" y accedemos a ella a través de un campo de solo lectura, no fue de solo lectura cuando se creó el objeto. No hay nada que impida que se modifique, excepto que el compilador detecta "hey, primero dijiste que no querías cambiarlo, ahora estás tratando de cambiarlo, ¿qué da? Una de esas dos decisiones debe estar equivocada".

Ahora, no hay ninguna promesa de que la reflexión pueda cambiarlo, pero no hay ninguna promesa de que no lo hará. En este momento, la forma en que funciona la reflexión y la forma en que solo funciona significa que puedes cambiarla. Al menos, tomaría mucho trabajo (tal vez con los costos que nos afectan a los usuarios, así como al equipo que necesita implementar ese trabajo) para detener a alguien que presuntamente se tomó la molestia de hacer esto porque pensaban que tenían una buena razón.

Tenga en cuenta que los permisos relacionados con la reflexión hacen dejar de Maquiavelo,

* En sentido estricto, Murphy estaba hablando con precisión cómo debemos diseñar cosas para impedir que la gente accidentalmente haciendo algo desastroso - readonly es un buen ejemplo, tapones que pueden' t físicamente estar enchufado en el camino equivocado alrededor de un mejor - y Maquiavelo estaba enseñando en lugar de practicar las técnicas.Sin embargo, no es para nada un dicho tan conciso.

+0

+1 Me gusta mucho esta metáfora. –

+0

@ p.s.w.g ¿la de Murphy y Maquiavelo? No puedo reclamar el crédito. El primer uso comparable (sobre "privado" en C++) que conozco fue el de Bjarne Stroustrup, aunque no sé si fue el primero. –

Cuestiones relacionadas