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

C# 为什么从接口继承的属性变为虚拟属性?,c#,reflection,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; } } 在类AAA2中,属性F

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

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; }
}
在类
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");
}
输出为:

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
有什么原因吗?

从:

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

如果需要确定此方法是否可重写,则仅检查
IsVirtual
是不够的,还需要检查
IsFinal
是否为false

以下是执行此检查的扩展方法:

public static bool IsOverridable(this MethodInfo method)
    => method.IsVirtual && !method.IsFinal;

对于C#中声明的
sealed override
(无论是否实现接口)方法(或属性的getter/setter等),您的方法也会返回false。在这些情况下,单独检查
.IsVirtual
将得到true。