为什么从接口继承的属性变为虚拟?

run*_*ack 39 c# reflection

假设我有一个接口和两个类,其中一个类实现了这个接口:

interface IAAA
{
    int F1 { get; set; }
}

class AAA1
{
    public int F1 { get; set; }
    public int F2 { get; set; }
}

class AAA2 : IAAA
{
    public int F1 { get; set; }
    public int F2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在类中AAA2,属性F1是从接口"继承"(我不确定)IAAA,然后我使用反射来检查属性是否是虚拟的:

Console.WriteLine("AAA1 which does not implement IAAA");
foreach (var prop in typeof(AAA1).GetProperties())
{
    var virtualOrNot = prop.GetGetMethod().IsVirtual ? "" : " not";
    Console.WriteLine($@"{prop.Name} is{virtualOrNot} virtual");
}

Console.WriteLine("AAA2 which implements IAAA");
foreach (var prop in typeof(AAA2).GetProperties())
{
    var virtualOrNot = prop.GetGetMethod().IsVirtual ? "" : " not";
    Console.WriteLine($"{prop.Name} is{virtualOrNot} virtual");
}
Run Code Online (Sandbox Code Playgroud)

输出是:

AAA1 which does not implement IAAA
F1 is not virtual
F2 is not virtual
AAA2 which implements IAAA
F1 is virtual
F2 is not virtual
Run Code Online (Sandbox Code Playgroud)

有什么理由吗?

vas*_*sib 33

MS docs的备注部分开始:

虚拟成员可以引用类中的实例数据,并且必须通过类的实例引用...公共语言运行库要求实现接口成员的所有方法都必须标记为虚拟; 因此,编译器标记该方法virtual final

如果您需要确定此方法是否可覆盖,那么检查IsVirtual是不够的,您还需要检查是否IsFinal为false.

这是一个执行此检查的扩展方法:

public static bool IsOverridable(this MethodInfo method)
    => method.IsVirtual && !method.IsFinal;
Run Code Online (Sandbox Code Playgroud)