Skip to content

"C#中反射(Reflection)对const、readonly及static的影响

using System; using System.Collections.Generic; using System.Text; using System.Reflection;

namespace ConsoleApplication1 { public class ReflectionTest { public const int test1 = 1; public readonly static int test2 = 1; public static int test3 = 1; public readonly int test4 = 1; }

class Program
{
    static void Main(string[] args)
    {
        ReflectionTest t = new ReflectionTest();
        FieldInfo f;

        // const int test1
        // const不应该被更改,猜想应当抛出异常
        // 运行中SetValue(t, 2);确实抛出System.FieldAccessException异常
        Console.WriteLine("test1=" + ReflectionTest.test1);
        f = typeof(ReflectionTest).GetField("test1");
        f.SetValue(t, 2);
        Console.WriteLine("test1=" + ReflectionTest.test1);

        // readonly static int test2
        // 因为readonly不进行编译时检查,编译通过,但是执行时应当出错
        // 但是实际中没有任何提示,也并未更改,错误被吃掉了!
        Console.WriteLine("test2=" + ReflectionTest.test2);
        f = typeof(ReflectionTest).GetField("test2");
        f.SetValue(t, 2);
        Console.WriteLine("test2=" + ReflectionTest.test2);

        // static int test3
        // static变量当然可以通过反射更改
        Console.WriteLine("test3=" + ReflectionTest.test3);
        f = typeof(ReflectionTest).GetField("test3");
        f.SetValue(t, 2);
        Console.WriteLine("test3=" + ReflectionTest.test3);

        // readonly int test4
        // 实例中的readonly变量可以通过反射更改其值
        // 因此,readonly变量的赋值方法总共有三种:
        // 1. 在声明时对readonly变量赋值;
        // 2. 在构造函数中对readonly变量赋值;
        // 3. 使用反射在实例生命期中对readonly变量赋值。
        Console.WriteLine("test4=" + t.test4);
        f = typeof(ReflectionTest).GetField("test4");
        f.SetValue(t, 2);
        Console.WriteLine("test4=" + t.test4);
    }
}

}

运行结果:

test1=1 未处理的异常: System.FieldAccessException: 无法设置常量字段。 在 System.Reflection.MdFieldInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureIn fo culture) 在 System.Reflection.FieldInfo.SetValue(Object obj, Object value) 在 ConsoleApplication1.Program.Main(String[] args) 位置 C:\Documents and Settings\Zheng Li\桌面\ConsoleApplication1\C onsoleApplication1\Program.cs:行号 28

注释掉第28行的结果:

test1=1 test1=1 test2=1 test2=1 test3=1 test3=2 test4=1 test4=2