我最近一直在研究providers,我遇到了一个有趣的情况,我想有一个抽象类,它有一个抽象的静态方法.我读了一些关于这个话题的帖子,这有点道理,但是有一个很好的清晰的解释吗?

推荐答案

静态方法本身并不是instantiated个,它们只是在没有对象引用的情况下可用.

对静态方法的调用是通过类名来完成的,而不是通过对象引用,调用它的中间语言(IL)代码将通过定义它的类的名称来调用抽象方法,而不一定是使用的类的名称.

让我举一个例子.

使用以下代码:

public class A
{
    public static void Test()
    {
    }
}

public class B : A
{
}

如果您调用B.Test,如下所示:

class Program
{
    static void Main(string[] args)
    {
        B.Test();
    }
}

那么Main方法中的实际代码如下所示:

.entrypoint
.maxstack 8
L0000: nop 
L0001: call void ConsoleApplication1.A::Test()
L0006: nop 
L0007: ret 

正如您所见,调用的是A.Test,因为它是定义它的类,而不是B.Test,尽管您可以这样编写代码.

如果你有class types个,就像在Delphi中一样,你可以使变量引用一个类型而不是一个对象,那么你会更多地使用虚拟的,从而抽象的静电方法(以及构造函数),但是它们是不可用的,因此静电调用在.NET中是非虚拟的.

我意识到IL设计人员可以允许编译代码来调用B.Test,并在运行时解析调用,但它仍然不是虚拟的,因为您仍然需要在那里编写某种类名.

虚拟方法和抽象方法只有在使用变量时才有用,在运行时,该变量可以包含许多不同类型的对象,因此需要为变量中的当前对象调用正确的方法.对于静态方法,无论如何都需要经过类名,因此要调用的确切方法在编译时是已知的,因为它不能也不会改变.

因此,虚拟/抽象静电方法在.NET中不可用.

.net相关问答推荐

如何将 select 语句详细信息提取到不同的方法中仍然保持Eager 加载?

等待时 Blazor 服务器按钮刷新

使用 Powershell TOM 在 SSAS 表格中创建分区

无法通过构建目标访问 dotnet 的环境变量

查找 2 个已知值之间的字符串

Erlang 的让它崩溃的哲学 - 适用于其他地方吗?

.gitignore 和 Visual Studio 项目:忽略 bin/Debug 目录但不忽略 bin/Release 目录

MongoDB C# 驱动程序 - 忽略绑定字段

在 WinForms 应用程序中查找焦点控件的首选方法是什么?

具有透明背景且包含不透明控件的 WPF 窗口

Select 文件夹对话框 WPF

使用只读属性或方法?

修剪数组中的所有字符串

C# 测试字符串是否为整数?

关于 Enumerable.Range 与传统 for 循环的 foreach 的思考

C#中的T是什么意思?

为什么会出现编译错误使用未分配的局部变量?

将 SignalR 2.0 .NET 客户端重新连接到服务器集线器的最佳实践

如何重新启动 WPF 应用程序?

如何从 HashSet 中检索实际项目?