阴影(VB.NET)和新(C#)之间的区别

M.A*_*nin 10 .net c# vb.net new-operator shadows

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

Cod*_*ray 13

它们完全相同. Shadows是C#的new关键字的VB.NET等价物.它们在语义上意味着相同的东西,并且它们编译成相同的IL.

在某些版本的Visual Studio中(我不确定是否仍然如此),Shadows在VB.NET项目中使用关键字具有隐藏Intellisense中具有相同名称的所有函数的效果.但这实际上并不是一种语言特征; 它是不是很清楚它是设计还是实施Intellisense的错误.如果您使用来自C#应用程序的相同VB.NET库,您将看到所有方法,就像它们被声明一样new.

  • @MAHanin正如其他答案和链接线程所解释的那样,在VB.NET中,`Public Shadows Function SomeMethod(SomeParam As String)As String`,带有`Shadows`,将隐藏`SomeMethod`的所有签名,而不仅仅是这个特定的签名.而`Public Overloads Function SomeMethod(SomeParam As String)As String`,带有`Overloads`,只隐藏这个特定的签名.在C#中,没有办法隐藏所有签名; 每个"新"只隐藏一个签名. (3认同)

Gia*_*lis 8

它们完全相同.

阴影概念并不在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
Run Code Online (Sandbox Code Playgroud)

而这个派生类:

Public Class DerivedClass
    Inherits BaseClass

    Public Shadows Function SomeMethod(SomeParam As String) As String
        Return "Derived from String"
    End Function
End Class
Run Code Online (Sandbox Code Playgroud)

现在考虑实施:

Dim DerivedInstance = New DerivedClass()
Run Code Online (Sandbox Code Playgroud)

DerivedInstance只有一个版本的SomeMethod,所有其他基本版本都被遮蔽了.

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

DerivedInstance阴影方法

要在VB.Net中执行隐藏,您仍然必须使用重载(或者如果基本方法被标记为覆盖,覆盖)关键字:

Public Class DerivedClass
    Inherits BaseClass

    Public Overloads Function SomeMethod(SomeParam As String) As String
        Return "Derived from String"
    End Function
End Class
Run Code Online (Sandbox Code Playgroud)

这是编译后发生的事情:

DerivedInstance隐藏方法

所以,在VB.Net中,如果你在一个与基类相匹配的签名上使用了重载关键字,你就会隐藏那个基本版本的方法,就像在c#中一样:

public class DerivedClass : BaseClass
{
    public new string SomeMethod(string someParam)
    {
        return "Derived from String";
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:这是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
}
Run Code Online (Sandbox Code Playgroud)

来自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
}
Run Code Online (Sandbox Code Playgroud)

所以....他们并不完全相同.

注意:在downvote之前......请....尝试.

  • 这是[来自另一个线程的相关答案](/sf/answers/333243011/)。 (2认同)
  • 这个答案是正确的。当基类的方法名称有两个签名,并且继承类仅提及其中一个签名时,则 C# 关键字“new”对应于 VB.NET 构造“Public Overloads Function SomeMethod(SomeParam As String) As String” ,而不是“公共阴影函数 SomeMethod(SomeParam As String) As String”。在 C# 中,也无法隐藏其他签名(当然,除非您在继承类中重复这两个签名)。C# 始终将“hidebysig”放入输出 CIL 中。在VB.NET中,您可以仅通过名称来隐藏。 (2认同)