我看到两种不同的行为基于我的应用程序运行的CLR。在一种情况下,它返回一个封闭类型的抽象属性,而另一个则不返回。由于财产是抽象的,感觉更像是第一个是正确的。
我已经通过在针对.NET-3.5 SP1的VS2010下编译以下内容进行了测试,然后将物理可执行文件复制到另一台具有不同CLR次要版本的计算机:
public abstract class BaseEntity<TId>
{
public abstract TId PK { get; set; }
}
public class DerivedEntity : BaseEntity<int>
{
public override int PK { get; set; }
}
class Program
{
static void Main(string[] args)
{
var derivedEntity = new DerivedEntity();
var type = derivedEntity.GetType();
var flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty;
foreach (var memberInfo in type.GetMember("PK", flags))
{
Console.WriteLine(
"Member: " + memberInfo.Name
+ " from " + memberInfo.DeclaringType);
}
Console.WriteLine("Running : " + Environment.Version);
Console.WriteLine("mscorlib: " + typeof(int).Assembly.GetName().Version);
}
}
在运行2.0.50727.4952的机器上,我看到以下输出:
Member: PK from MemberInfoTest.DerivedEntity
Running : 2.0.50727.4952
mscorlib: 2.0.0.0
在运行2.0.50727.3615的机器上,我得到不同的输出:
Member: PK from MemberInfoTest.DerivedEntity
Member: PK from MemberInfoTest.BaseEntity`1[System.Int32]
Running : 2.0.50727.3615
mscorlib: 2.0.0.0
上述差异导致AmbiguousMatchException
在各种情况下。哪一种行为是正确的,另一种是“修复”吗?
编辑:我刚刚测试了目标CLR-4运行时,并且在任何一种情况下都没有返回抽象的关闭属性,进一步表明我的第一个行为是正确的。
答案 0 :(得分:3)
我不确定为什么会出现这种情况。我的猜测是你看到RTM和SP1 CLR,并且反射在两个版本之间存在细微差别/错误。
您可以通过设置PK
来声明您希望在GetMembers
开启的特定类型上声明的BindingFlags.DeclaredOnly
成员,从而解决此问题。 DeclaredOnly
会将返回成员限制为仅在特定类型上声明的成员。它将过滤掉在父类型上声明的任何成员。