众所周知,C#反射Type类可以获取到字段信息(FieldInfo)及属性信息(PropertyInfo),他们的基类是MemberInfo。
那么问题来了,再FieldInfo和Property Info中有一个方法为GetValue(Object obj),可以获取引用对象下的具备该字段/属性的值,最近就遇到了问题需要反射中来判断是否引用的同一对象,那么这个GetValue返回的到底是原来成员的引用还是复制的值。于是做了一个测试,测试如下:
public class TestClass
{
public static int a = 5;
public static int b = 5;
}
public static TestClass c = new TestClass();
//测试的入口
public static void Test()
{
//object c2 = System.Activator.CreateInstance(typeof(TestClass), true);
bool result;
object v1 = typeof(TestClass).GetField("a").GetValue(c);
object v2 = typeof(TestClass).GetField("a").GetValue(c);
//if (v1 == v2) result = true;
//else result = false;
Console.Write("IsEquals:" + object.ReferenceEquals(v1,v2));
}
结果是False,除了使用Int32类型测试以外我还测试了结构体类型结果返回的也是False。所以值类型的成员GetValue返回的仅仅是值而不是原对象的引用。那么引用类型的成员结果如何,于是我又做了一个测试:
public class TestClass
{
public static int a = 5;
public static TestClass b = new TestClass();
public class TestClass2 { }
}
public static TestClass c = new TestClass();
//测试的入口
public static void Test()
{
//object c2 = System.Activator.CreateInstance(typeof(TestClass), true);
bool result;
object v1 = typeof(TestClass).GetField("b").GetValue(c);
object v2 = typeof(TestClass).GetField("b").GetValue(c);
//if (v1 == v2) result = true;
//else result = false;
Console.Write("IsEquals:" + object.ReferenceEquals(v1,v2));
}
返回结果是True,并且我用string类型也测试过返回仍然为True。
结论:值类型的成员GetValue返回的仅仅是值而不是原对象的引用,引用类型的成员GetValue返回的是引用的对象。C#这么做的原因我不懂,可能大概是和线程栈与托管堆存储有关吧。
最后还是没有解决我的问题,由于值类型返回的仅仅是值,我仍然没有办法在反射中判断是否引用同一对象。