【问题标题】:Why does a property inherited from an interface become virtual?为什么从接口继承的属性变成虚拟的?
【发布时间】:2018-11-27 03:58:56
【问题描述】:

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

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

有什么原因吗?

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    来自remarks section of MS docs

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

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

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

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

    【讨论】:

    • 对于在 C# 中声明的 sealed override 的方法(或属性的 getter/setter 等),您的方法也会返回 false(无论它是否实现接口)。在这些情况下单独检查 .IsVirtual 会产生 true。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2012-10-11
    • 2017-05-12
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    相关资源
    最近更新 更多