C# 如何判断MemberInfo是否表示覆盖

C# 如何判断MemberInfo是否表示覆盖,c#,reflection,polymorphism,C#,Reflection,Polymorphism,给定以下代码: public class Base { public virtual void Method() { } } public class Derived : Base { public override void Method() { } } ... var baseMethodInfo = typeof(Base).GetMember("Method")[0]; var derivedMethodInfo = typeof(Derived).GetMembe

给定以下代码:

public class Base {
    public virtual void Method() { }
}

public class Derived : Base {
    public override void Method() { }
}

...

var baseMethodInfo = typeof(Base).GetMember("Method")[0];
var derivedMethodInfo = typeof(Derived).GetMember("Method")[0];
是否可以确定derivedMethodInfo是否表示重写基类中另一个方法声明的方法声明

据观察,如果
方法
在基类中声明为抽象(且未实现),derivedMethodInfo.DeclaringType将作为基类出现,这在阅读@EricLippert的注释后是有意义的。我注意到在本例中,由于派生类重新声明了该方法,因此
derivedMethodInfo.DeclaringType==derivedMethodInfo.ReflectedType
,即。衍生的

baseMethodInfo和derivedMethodInfo之间似乎没有任何联系,只是它们的名称相同,各自的声明类型出现在同一继承链中。有没有更好的连接方式

我提出这一问题的原因是,通过反思,似乎无法区分前面的例子和下面的例子:

public class Base {
    public virtual void Method() { }
}

public class Derived : Base {
    public new void Method() { }
}

在这种情况下,派生类也声明并反映了名为Method的成员。

隐藏
虚拟
方法的方法将在
属性中设置
VtableLayoutMask
标志

请注意,普通的
virtual
方法(没有与基类型类似的名称)也将设置此标志


此标志似乎表示该方法在VTable中引入了一个新条目。

隐藏
虚拟
方法的方法将在
属性
中设置
VtableLayoutMask
标志

请注意,普通的
virtual
方法(没有与基类型类似的名称)也将设置此标志


此标志似乎表示该方法在VTable中引入了一个新条目。

有一个更具体的类
MethodInfo
,它派生自
MemberInfo
。请注意,并非所有类型的成员都可以是虚拟的(例如,字段不能是虚拟的)

如果你说

var derivedMethodInfo = typeof(Derived).GetMethod("Method");
然后你可以检查一下

derivedMethodInfo.GetBaseDefinition() == derivedMethodInfo

或者不是。查看其中的代码示例。

有一个更具体的类
MethodInfo
,它派生自
MemberInfo
。请注意,并非所有类型的成员都可以是虚拟的(例如,字段不能是虚拟的)

如果你说

var derivedMethodInfo = typeof(Derived).GetMethod("Method");
然后你可以检查一下

derivedMethodInfo.GetBaseDefinition() == derivedMethodInfo

或者不是。看看他们在哪里还有一个代码示例。

只是在LINQPad中玩而已,事实确实如此+我很值得!如果我理解您的回答,听起来好像
VtableLayoutMask
属性指示该方法是否可以重写,而不是是否正在重写。特别是,如果新方法被声明为
public new virtual void method()
,那么同样无法判断它是否隐藏了基本方法(这里没有)。@CSJ:no.
new virtual
具有
VtableLayoutMask
(因为它引入了一个新的Vtable条目)<代码>覆盖
没有。@SLaks:啊,对不起,我误解了。我认为阴影意味着压倒一切;事实上,这意味着使用
new
关键字。总之,我应该查找no
VtableLayoutMask
attribute.VtableLayoutMask实际上不是属性的名称,而是位掩码。调试器在枚举方面不够聪明,无法显示良好的信息。位掩码只测试属性中的一位,您确实需要查找MethodAttributes.NewSlot。如果未设置,则可以假定默认值MethodAttributes.ReuseSlot只是在LINQPad中使用,事实确实如此+我很值得!如果我理解您的回答,听起来好像
VtableLayoutMask
属性指示该方法是否可以重写,而不是是否正在重写。特别是,如果新方法被声明为
public new virtual void method()
,那么同样无法判断它是否隐藏了基本方法(这里没有)。@CSJ:no.
new virtual
具有
VtableLayoutMask
(因为它引入了一个新的Vtable条目)<代码>覆盖没有。@SLaks:啊,对不起,我误解了。我认为阴影意味着压倒一切;事实上,这意味着使用
new
关键字。总之,我应该查找no
VtableLayoutMask
attribute.VtableLayoutMask实际上不是属性的名称,而是位掩码。调试器在枚举方面不够聪明,无法显示良好的信息。位掩码只测试属性中的一位,您确实需要查找MethodAttributes.NewSlot。如果未设置,则可以假定默认值MethodAttributes.ReuseSlot应该区分这两种情况。@JeppeStigNielsen:是;这是一个更好的答案。@JeppeStigNielsen:你完全正确。我错过了它,因为我使用的是MemberInfo而不是MethodInfo。如果你能给我一个答案,我会接受的!我想这两种情况应该有所区别。@JeppeStigNielsen:是的;这是一个更好的答案。@JeppeStigNielsen:你完全正确。我错过了它,因为我使用的是MemberInfo而不是MethodInfo。如果你能给我一个答案,我会接受的!