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

[code=’c#’]
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);
}
}
}
[/code]

运行结果:
[code=’sh’]
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
[/code]

注释掉第28行的结果:
[code=’sh’]
test1=1
test1=1
test2=1
test2=1
test3=1
test3=2
test4=1
test4=2
[/code]

1 comment

  1. 对于错误,总结:
    1. 编译时检查错误 (极赞)!
    2. 编译时没有检查,运行时抛异常(赞)!!
    2. 编译时没有检查,运行时不抛异常(搓)!!!
    The worst thing is to ignore the exception cases in silence.

发表评论