¿Puedo cambiar un campo privado de solo lectura en C# usando la reflexión?
Me pregunto, dado que se pueden hacer muchas cosas mediante la reflexión, ¿puedo cambiar un campo privado de solo lectura después de que el constructor haya completado su ejecución?
(nota: solo curiosidad)
public class Foo
{
private readonly int bar;
public Foo(int num)
{
bar = num;
}
public int GetBar()
{
return bar;
}
}
Foo foo = new Foo(123);
Console.WriteLine(foo.GetBar()); // display 123
// reflection code here...
Console.WriteLine(foo.GetBar()); // display 456
Puede:
typeof(Foo)
.GetField("bar",BindingFlags.Instance|BindingFlags.NonPublic)
.SetValue(foo,567);
Lo obvio es probarlo:
using System;
using System.Reflection;
public class Test
{
private readonly string foo = "Foo";
public static void Main()
{
Test test = new Test();
FieldInfo field = typeof(Test).GetField
("foo", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(test, "Hello");
Console.WriteLine(test.foo);
}
}
Esto funciona bien. (Curiosamente, Java tiene reglas diferentes: debe configurar explícitamente que Field
sean accesibles y, de todos modos, solo funcionará, por ejemplo, en campos).
Estoy de acuerdo con las otras respuestas en que funciona en general y especialmente con el comentario de E. Lippert de que este no es un comportamiento documentado y, por lo tanto, no es un código preparado para el futuro.
Sin embargo, también notamos otro problema. Si está ejecutando su código en un entorno con permisos restringidos, es posible que obtenga una excepción.
Acabamos de tener un caso en el que nuestro código funcionó bien en nuestras máquinas, pero recibimos un aviso VerificationException
cuando el código se ejecutó en un entorno restringido. El culpable fue una llamada de reflexión al creador de un campo de solo lectura. Funcionó cuando eliminamos la restricción de solo lectura de ese campo.