GetMember应该在封闭类型上返回一个抽象属性吗?

时间:2011-02-02 23:00:35

标签: c# reflection clr

我看到两种不同的行为基于我的应用程序运行的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运行时,并且在任何一种情况下都没有返回抽象的关闭属性,进一步表明我的第一个行为是正确的。

1 个答案:

答案 0 :(得分:3)

我不确定为什么会出现这种情况。我的猜测是你看到RTM和SP1 CLR,并且反射在两个版本之间存在细微差别/错误。

您可以通过设置PK来声明您希望在GetMembers开启的特定类型上声明的BindingFlags.DeclaredOnly成员,从而解决此问题。 DeclaredOnly会将返回成员限制为仅在特定类型上声明的成员。它将过滤掉在父类型上声明的任何成员。