答案是:不,这不是错误。区别在于ReflectedType。
所以这里真正的问题是:有没有办法比较两个PropertyInfo
对象,对于相同的属性,但从不同的类型反映,以便它返回true
?
原始问题
此代码使用两种不同的方式为相同的属性PropertyInfo
生成两个对象。因此,这些属性信息以某种方式进行了不同的比较。我已经失去了一些时间试图弄清楚这一点。
我究竟做错了什么?
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace TestReflectionError
{
class Program
{
static void Main(string[] args)
{
Console.BufferWidth = 200;
Console.WindowWidth = 200;
Expression<Func<object>> expr = () => ((ClassA)null).ValueA;
PropertyInfo pi1 = (((expr as LambdaExpression)
.Body as UnaryExpression)
.Operand as MemberExpression)
.Member as PropertyInfo;
PropertyInfo pi2 = typeof(ClassB).GetProperties()
.Where(x => x.Name == "ValueA").Single();
Console.WriteLine("{0}, {1}, {2}, {3}, {4}", pi1, pi1.DeclaringType, pi1.MemberType, pi1.MetadataToken, pi1.Module);
Console.WriteLine("{0}, {1}, {2}, {3}, {4}", pi2, pi2.DeclaringType, pi2.MemberType, pi2.MetadataToken, pi2.Module);
// these two comparisons FAIL
Console.WriteLine("pi1 == pi2: {0}", pi1 == pi2);
Console.WriteLine("pi1.Equals(pi2): {0}", pi1.Equals(pi2));
// this comparison passes
Console.WriteLine("pi1.DeclaringType == pi2.DeclaringType: {0}", pi1.DeclaringType == pi2.DeclaringType);
Console.ReadKey();
}
}
class ClassA
{
public int ValueA { get; set; }
}
class ClassB : ClassA
{
}
}
这里的输出是:
Int32 ValueA, TestReflectionError.ClassA, Property, 385875969, TestReflectionError.exe
Int32 ValueA, TestReflectionError.ClassA, Property, 385875969, TestReflectionError.exe
pi1 == pi2: False
pi1.Equals(pi2): False
pi1.DeclaringType == pi2.DeclaringType: True
罪魁祸首:PropertyInfo.ReflectedType
我发现这两个对象之间有区别……它在ReflectedType
. 文档是这样说的:
获取用于获取此成员的类对象。