¿Puedo cambiar un campo privado de solo lectura en C# usando la reflexión?

Resuelto Ron Klein asked hace 15 años • 9 respuestas

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
Ron Klein avatar Jun 01 '09 20:06 Ron Klein
Aceptado

Puede:

typeof(Foo)
   .GetField("bar",BindingFlags.Instance|BindingFlags.NonPublic)
   .SetValue(foo,567);
Philippe Leybaert avatar Jun 01 '2009 13:06 Philippe Leybaert

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 Fieldsean accesibles y, de todos modos, solo funcionará, por ejemplo, en campos).

Jon Skeet avatar Jun 01 '2009 13:06 Jon Skeet

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 VerificationExceptioncuando 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.

Andreas avatar Feb 26 '2013 11:02 Andreas