【问题标题】:Difference between Shadows (VB.NET) and New (C#)阴影 (VB.NET) 和新建 (C#) 之间的区别
【发布时间】:2012-01-24 09:57:20
【问题描述】:

来自一个头脑简单的简单问题: VB.NET 中的Shadows 关键字和C# 中的New 关键字有什么区别? (当然是关于方法签名)。

【问题讨论】:

    标签: c# .net vb.net new-operator shadows


    【解决方案1】:

    它们相同。

    Shadowing 概念在 C# 中不存在

    考虑一个带有一些重载的 vb.net 基类:

    Public Class BaseClass
        Public Function SomeMethod() As String
            Return String.Empty
        End Function
        Public Function SomeMethod(SomeParam As String) As String
            Return "Base from String"
        End Function
    
        Public Function SomeMethod(SomeParam As Integer) As String
            Return "Base from Integer"
        End Function
        Public Function SomeMethod(SomeParamB As Boolean) As String
            Return "Base from Boolean"
        End Function
    End Class
    

    还有这个派生类:

    Public Class DerivedClass
        Inherits BaseClass
    
        Public Shadows Function SomeMethod(SomeParam As String) As String
            Return "Derived from String"
        End Function
    End Class
    

    现在考虑实现:

    Dim DerivedInstance = New DerivedClass()
    

    DerivedInstance 仅有 一个 版本的 SomeMethod,所有 其他基本版本已隐藏

    如果您在 C# 项目中编译和引用程序集,您可以看到会发生什么:

    DerivedInstance shadows method

    要在 VB.Net 中执行 hiding,您仍然必须使用 overloads(或 overrides,如果基本方法标记为 >overridable) 关键字:

    Public Class DerivedClass
        Inherits BaseClass
    
        Public Overloads Function SomeMethod(SomeParam As String) As String
            Return "Derived from String"
        End Function
    End Class
    

    这就是编译后发生的事情:

    DerivedInstance hide method

    因此,在 VB.Net 中,如果您在与基类匹配的签名上使用 overloads 关键字,则您将 隐藏该方法的基础版本,就像你在 c# 中一样:

    public class DerivedClass : BaseClass
    {
        public new string SomeMethod(string someParam)
        {
            return "Derived from String";
        }
    }
    

    编辑:这是 IL 代码:

    来自 C#:

    .method public hidebysig specialname rtspecialname instance void .ctor () cil managed 
    {
        IL_0000: ldarg.0
        IL_0001: call instance void Shadowing_CS.BaseClass::.ctor()
        IL_0006: ret
    }
    
    .method public hidebysig instance string SomeMethod (
            string s
        ) cil managed 
    {
        IL_0000: ldstr "Derived from string"
        IL_0005: ret
    }
    

    来自 VB:

    .method public specialname rtspecialname instance void .ctor () cil managed 
    {
        IL_0000: ldarg.0
        IL_0001: call instance void Shadowing_VB.BaseClass::.ctor()
        IL_0006: ret
    }
    
    .method public instance string SomeMethod (
            string s
        ) cil managed 
    {
        IL_0000: ldstr "Derived from string"
        IL_0005: ret
    }
    

    所以....它们相同。

    注意:在投反对票之前......请......试试吧。

    【讨论】:

    • 这个答案是正确的。当基类对方法名称有两个签名,而继承类只提及其中一个签名时,则 C# 关键字 new 对应于 VB.NET 构造 Public Overloads Function SomeMethod(SomeParam As String) As String,而不是 Public Shadows Function SomeMethod(SomeParam As String) As String。在 C# 中,也无法隐藏 其他签名(当然,除非您在继承类中重复这两个签名)。 C# 总是将hidebysig 放在输出 CIL 中。在 VB.NET 中,您可以单独按名称隐藏。
    • 应该有一个特殊的徽章,用于在问题发布六年后提出正确答案
    【解决方案2】:

    它们是相同的,只是实现相同 OOP 概念的语言特定关键字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 2010-11-26
      • 2012-08-16
      • 2011-01-29
      • 1970-01-01
      相关资源
      最近更新 更多